WP8.1学习系列(第二十六章)——控件模板
在 XAML 框架中,如果要自定义控件的可视结构和可视行为,请创建控件模板。控件有多个属性,如 Background、Foreground 以及FontFamily,可以设置这些属性以指定控件外观的多个方面。但是可以通过设置这些属性所做的更改有限。可以使用 ControlTemplate 类创建提供其他自定义的模板。在此处,我们介绍如何创建 ControlTemplate 以自定义 CheckBox 控件的外观。
路线图: 本主题与其他主题有何关联?请参阅:
自定义控件模板示例
在默认情况下,CheckBox 控件将其内容(字符串或 CheckBox 旁的对象)放在选择框的右侧。这是 CheckBox 的可视结构。在默认情况下,复选标记表示用户已选定 CheckBox。这是 CheckBox 的可视行为。你可以通过为 CheckBox 创建 ControlTemplate 来更改这些特性。例如,假定你想要让复选框的内容显示在选择框下方,并且你想要用 X 来表示用户已选定复选框。你可以在 CheckBox 的 ControlTemplate 中指定这些特性。
下面是分别在 Unchecked
、Checked
和 Indeterminate
状态下使用默认 ControlTemplate 的 CheckBox。
要为控件使用自定义模板,请将 ControlTemplate 分配给控件的 Template 属性。下面是使用称为CheckBoxTemplate1
的 ControlTemplate 的 CheckBox。我们在下一节介绍 ControlTemplate 的 Extensible Application Markup Language (XAML)。
<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>
下面是在应用模板后,CheckBox 在 Unchecked
、Checked
和 Indeterminate
状态下的外观。
指定控件的可视结构。
当你创建 ControlTemplate 时,要结合 FrameworkElement 对象来构建一个单一的控件。ControlTemplate只能有一个 FrameworkElement 作为其根元素。该根元素通常包含其他 FrameworkElement 对象。这些对象的组合组成控件的可视结构。
下面的 XAML 为 CheckBox 创建了 ControlTemplate,指定控件的内容显示在选择框的下方。根元素为Border。该示例指定 Path 来创建 X,表示用户已选定 CheckBox,并用 Ellipse 表示不确定状态。请注意,Opacity 在 PathEllipse 上设置为 0,因此在默认情况下,两者都不会显示。
<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Rectangle x:Name="NormalRectangle"
Fill="{ThemeResource CheckBoxBackgroundThemeBrush}"
Stroke="{ThemeResource CheckBoxBorderThemeBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False" Height="21" Width="21"/>
<!-- Create an X to indicate that the CheckBox is selected. -->
<Path x:Name="CheckGlyph"
Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}" FlowDirection="LeftToRight"
Height="14" Width="16" Opacity="0" Stretch="Fill"/>
<Rectangle x:Name="IndeterminateGlyph"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Height="9" Width="9" Opacity="0" UseLayoutRounding="False" />
<ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" Grid.Row="1"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</ControlTemplate>
指定控件的可视行为
可视行为指定控件在确定状态下的外观。CheckBox 控件具有 3 中复选状态:Checked
、Unchecked
和Indeterminate
。IsChecked 属性的值确定 CheckBox 的状态,其状态确定方框中显示的符号。
下表列出了 IsChecked 的可能值,CheckBox 的响应状态,以及 CheckBox 的外观。
IsChecked 值 | CheckBox 状态 | CheckBox 外观 |
true | Checked |
包含 "X"。 |
false | Unchecked |
空白。 |
null | Indeterminate |
包含一个矩形。 |
使用 VisualState 对象可指定控件在确定状态下的外观。VisualState 包含可更改 ControlTemplate 中元素外观的 Storyboard。当控件切换到 VisualState.Name 属性指定的状态时,Storyboard 就会开始。当控件退出该状态时,Storyboard 就会停止。你可以将 VisualState 对象添加到 VisualStateGroup 对象。还可以将VisualStateGroup 对象添加到 VisualStateManager.VisualStateGroups 附加的属性,这些对象在ControlTemplate 的根 FrameworkElement 上设置。
以下 XAML 介绍在 Checked
、Unchecked
和 Indeterminate
状态下的 VisualState 对象。该示例在 Border 上设置 VisualStateManager.VisualStateGroups 附加属性,它是 ControlTemplate 的根元素。Checked
VisualState 指定名为 CheckGlyph
的 Path(已在前面的示例中介绍)的 Opacity 为 1。Indeterminate
VisualState 指定名为 IndeterminateGlyph
的 Ellipse 的 Opacity 为 1。Unchecked
VisualState 没有 Storyboard,因此 CheckBox 恢复为默认外观。
<ControlTemplate TargetType="CheckBox" x:Key="CheckBoxTemplate1">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="CheckGlyph"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="IndeterminateGlyph"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Rectangle x:Name="NormalRectangle"
Fill="{ThemeResource CheckBoxBackgroundThemeBrush}"
Stroke="{ThemeResource CheckBoxBorderThemeBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False" Height="21" Width="21"/>
<!-- Create an X to indicate that the CheckBox is selected. -->
<Path x:Name="CheckGlyph"
Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}" FlowDirection="LeftToRight"
Height="14" Width="16" Opacity="0" Stretch="Fill"/>
<Rectangle x:Name="IndeterminateGlyph"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Height="9" Width="9" Opacity="0" UseLayoutRounding="False" />
<ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" Grid.Row="1"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</ControlTemplate>
为了更深入地理解 VisualState 对象的工作机制,请思考当 CheckBox 从 Unchecked
状态切换到 Checked
状态,然后切换到 Indeterminate
状态,然后又恢复为 Unchecked
状态时,会发生什么。下表介绍了这些转换。
状态转换 | 引发的结果 | 转换完成时的 CheckBox 外观 |
从 Unchecked 到 Checked 。 |
Checked VisualState 的 Storyboard 开始,所以 CheckGlyph 的 Opacity为 1。 |
显示 X。 |
从 Checked 到Indeterminate 。 |
Indeterminate VisualState 的 Storyboard 开始,所以IndeterminateGlyph 的 Opacity 为 1。 Checked VisualState 的Storyboard 结束,所以 CheckGlyph 的 Opacity 为 0。 |
显示一个圆形。 |
从Indeterminate 到 Unchecked 。 |
Indeterminate VisualState 的 Storyboard 结束,所以IndeterminateGlyph 的 Opacity 为 0。 |
不显示任何符号。 |
有关如何创建控件视觉状态和(特别是)如何使用 Storyboard 类和动画类型的详细信息,请参阅视觉状态的情节提要动画。
使用工具轻松处理主题
将主题应用到控件的一种快捷方式是,在 Microsoft Visual Studio XAML 设计界面上,右键单击控件并选择“编辑主题”或“编辑样式”(取决于右键单击的控件)。然后,通过选择“应用资源”来应用现有主题,或通过选择“创建空项”来定义一个新主题。
控件和辅助功能
为控件创建新模板时,除了可能会更改控件的行为和视觉外观外,还可能会更改控件自行代表辅助功能框架的方式。Windows 运行时支持 Microsoft UI 自动化框架用于辅助功能。所有默认控件及其模板都支持适用于控件的用途和功能的常见 UI 自动化控件类型和模式。这些控件类型和模式由 UI 自动化客户端(如辅助技术)进行解释,这样允许控件作为较大辅助应用 UI 的一部分进行访问。
若要分离基本控件逻辑以及符合 UI 自动化的某些体系结构要求,控件类在独立类(自动化对等)中包含辅助功能支持。有时自动化对等会与控件模板有交互,因为对等预期某些命名部件存在于模板中,以便可能会使用诸如允许辅助技术调用按钮操作的功能。
创建全新的自定义控件时,有时还希望随之一起新建自动化对等。有关详细信息,请参阅自定义的自动化对等。
了解有关控件默认模板的详细信息
如果你查看添加控件和内容下的各种主题,会发现一些记录了现有 Windows 运行时控件的默认控件模板的主题。例如,存在名为 AppBar 样式和模板的主题,它是添加应用栏下的子主题。
记录了 Windows 运行时控件样式和模板的主题向你显示的起始 XAML 摘录与使用之前描述的编辑主题或编辑样式技术时看到的相同。每个主题都将列出视觉状态的名称、使用的主题资源,以及包含该模板的样式的完整 XAML。如果你已开始修改模板并要查看原始模板的外观,或者想要验证你的新模板是否具有所有所需的命名视觉状态,这些主题将是非常有用的指南。
控件模板中的主题资源
对于 XAML 模板中的某些属性,你可能已注意到使用 ThemeResource 标记扩展的资源引用。这是一种可使单个控件模板使用资源的技术,这些资源可能采用不同的值,具体取决于当前哪个主题处于活动状态。这对于画笔和颜色尤其重要,因为主题的主要目的是使用户选择应用于整个系统的是深色主题、浅色主题,还是高对比度主题。使用 XAML 资源系统的应用可以使用适合该主题的资源集,以便应用 UI 中的主题选择可以反映用户的整个系统的主题选择。
添加控件和内容下还特别提供了其他主题,以记录现有 Windows 运行时控件的默认控件模板。作为此内容的一部分,这些主题还列出了默认模板使用的主题资源(主要是画笔)以及它们在每个主题下的值。同样,完整的主题资源集记录在 XAML 主题资源引用中。
WP8.1学习系列(第二十六章)——控件模板的更多相关文章
- WP8.1学习系列(第二十五章)——控件样式
XAML 框架提供许多自定义应用外观的方法.通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 路线图: 本主题与其他主题有何关联?请参阅: 使用 C# 或 Visua ...
- WP8.1学习系列(第二十二章)——在页面之间导航
在本文中 先决条件 创建导航应用 Frame 和 Page 类 页面模板中的导航支持 在页面之间传递信息 缓存页面 摘要 后续步骤 相关主题 重要的 API Page Frame Navigation ...
- WP8.1学习系列(第二十四章)——Json解析
.net已经集成了json解析,类名叫DataContractJsonSerializer DataContractJsonSerializer 类型公开以下成员. 构造函数 名称 说明 Da ...
- WP8.1学习系列(第十六章)——交互UX之命令模式
命令模式 在本文中 命令类型 命令放置 相关主题 你可以在应用商店应用的几个曲面中放置命令和控件,包括应用画布.弹出窗口.对话框和应用栏.在正确的时间选择合适的曲面可能就是易于使用的应用和很难使用 ...
- WP8.1学习系列(第十九章)——事件和路由事件概述
我们将介绍在使用 C#.Visual Basic 或 Visual C++ 组件扩展 (C++/CX) 作为编程语言并使用 XAML 进行 UI 定义时,针对 Windows 运行时应用的事件的编程概 ...
- WP8.1学习系列(第十二章)——全景控件Panorama开发指南
2014/6/18 适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1 全景体验是本机 Windows ...
- 【WPF学习】第二十六章 Application类——应用程序的生命周期
在WPF中,应用程序会经历简单的生命周期.在应用程序启动后,将立即创建应用程序对象,在应用程序运行时触发各种应用程序事件,你可以选择监视其中的某些事件.最后,当释放应用程序对象时,应用程序将结束. 一 ...
- 【WPF学习】第十九章 控件类
WPF窗口充满了各种元素,但这些元素中只有一部分是控件.在WPF领域,控件通常被描述为与用户交互的元素——能接收焦点并接受键盘或鼠标输入的元素.明显的例子包括文本框和按钮.然而,这个区别有时有些模糊. ...
- “全栈2019”Java多线程第二十六章:同步方法生产者与消费者线程
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
随机推荐
- 下载android源码
http://source.android.com Step 1.按照http://source.android.com/source/initializing.html配置好android编译环境 ...
- Python 获取CentOS主机信息
Python 获取主机IP地址 #!/usr/bin/env python #coding:utf-8 import os ip=os.popen("ifconfig eth0|grep ' ...
- 由SecureCRT命令行快捷键谈学习思想
由学习linux SecureCRT命令行常用快捷键开始谈起! 1)老男孩说,抓重点(重点非难点) 任何一个领域.学科,任何一个职位.工作,都有学不完的知识,优秀的学生总能抓住重点去学习,如果泛泛的去 ...
- 【NLP】文本相似度
http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html
- VCL 中的 Windows API 函数(2): ActivateKeyboardLayout
ActivateKeyboardLayout 分别在 Controls.DBGrids.Grids 单元用到, 基本都是如下语句: ActivateKeyboardLayout(Screen.Defa ...
- 小程序实现textarea随输入的文字行数变化高度自动增加
参考链接:https://blog.csdn.net/liuwengai/article/details/78987957 该实现方法是根据上面的链接改编为小程序的实现,代码如下: wxml: < ...
- text/html和text/plain的区别
1.text/html的意思是将文件的content-type设置为text/html的形式,浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理. 2.text/plain的意思是 ...
- Servlet3简介
servlet基础知识:http://blog.csdn.net/chjttony/article/details/6086292 ServletContext相关知识:http://blog.csd ...
- 运行jsp常犯的错误
error 未启动tomcat服务 tomcat端口是否已改动 404: 未部署web应用 运行时URL输入错误 检查文件的存放位置(存放文件的目录无法对外引用,如WEB-INF , META-INF ...
- Python下字符画(ascii art)生成
之前在b站上看到有人用C写了个脚本把妹抖龙op转换成字符画的形式输出了,感觉比较好玩在下就用python也写了一遍(主要是因为python比较简单好用).这里就这里就不介绍字符画了,因为能搜到这个的肯 ...