WP8.1学习系列(第二十六章)——控件模板

在本文中

在 XAML 框架中,如果要自定义控件的可视结构和可视行为,请创建控件模板。控件有多个属性,如 BackgroundForeground 以及FontFamily,可以设置这些属性以指定控件外观的多个方面。但是可以通过设置这些属性所做的更改有限。可以使用 ControlTemplate 类创建提供其他自定义的模板。在此处,我们介绍如何创建 ControlTemplate 以自定义 CheckBox 控件的外观。

路线图: 本主题与其他主题有何关联?请参阅:

自定义控件模板示例

在默认情况下,CheckBox 控件将其内容(字符串或 CheckBox 旁的对象)放在选择框的右侧。这是 CheckBox 的可视结构。在默认情况下,复选标记表示用户已选定 CheckBox。这是 CheckBox 的可视行为。你可以通过为 CheckBox 创建 ControlTemplate 来更改这些特性。例如,假定你想要让复选框的内容显示在选择框下方,并且你想要用 X 来表示用户已选定复选框。你可以在 CheckBox 的 ControlTemplate 中指定这些特性。

下面是分别在 UncheckedChecked 和 Indeterminate 状态下使用默认 ControlTemplate 的 CheckBox

要为控件使用自定义模板,请将 ControlTemplate 分配给控件的 Template 属性。下面是使用称为CheckBoxTemplate1 的 ControlTemplate 的 CheckBox。我们在下一节介绍 ControlTemplate 的 Extensible Application Markup Language (XAML)。

XAML

<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>

下面是在应用模板后,CheckBox 在 UncheckedChecked 和 Indeterminate 状态下的外观。

指定控件的可视结构。

当你创建 ControlTemplate 时,要结合 FrameworkElement 对象来构建一个单一的控件。ControlTemplate只能有一个 FrameworkElement 作为其根元素。该根元素通常包含其他 FrameworkElement 对象。这些对象的组合组成控件的可视结构。

下面的 XAML 为 CheckBox 创建了 ControlTemplate,指定控件的内容显示在选择框的下方。根元素为Border。该示例指定 Path 来创建 X,表示用户已选定 CheckBox,并用 Ellipse 表示不确定状态。请注意,Opacity 在 PathEllipse 上设置为 0,因此在默认情况下,两者都不会显示。

XAML

<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 中复选状态:CheckedUnchecked 和IndeterminateIsChecked 属性的值确定 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 介绍在 CheckedUnchecked 和 Indeterminate 状态下的 VisualState 对象。该示例在 Border 上设置 VisualStateManager.VisualStateGroups 附加属性,它是 ControlTemplate 的根元素。CheckedVisualState 指定名为 CheckGlyph 的 Path(已在前面的示例中介绍)的 Opacity 为 1。IndeterminateVisualState 指定名为 IndeterminateGlyph 的 Ellipse 的 Opacity 为 1。UncheckedVisualState 没有 Storyboard,因此 CheckBox 恢复为默认外观。

XAML

<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 CheckedVisualState 的 Storyboard 开始,所以 CheckGlyph 的 Opacity为 1。 显示 X。
从 Checked 到Indeterminate IndeterminateVisualState 的 Storyboard 开始,所以IndeterminateGlyph 的 Opacity 为 1。 CheckedVisualState 的Storyboard 结束,所以 CheckGlyph 的 Opacity 为 0。 显示一个圆形。
Indeterminate到 Unchecked IndeterminateVisualState 的 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 主题资源引用中。

时间: 2024-10-05 15:41:37

WP8.1学习系列(第二十六章)——控件模板的相关文章

WP8.1学习系列(第二十五章)——控件样式

XAML 框架提供许多自定义应用外观的方法.通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 路线图: 本主题与其他主题有何关联?请参阅: 使用 C# 或 Visual Basic 的 Windows 运行时应用的路线图 使用 C++ 的 Windows 运行时应用的路线图 应用功能大全系列中突出显示的 Windows 应用商店应用 UI 详细信息 本主题包含下列部分: 先决条件 样式基础知识 应用隐式或显式样式 使用基于样式 使用工具轻松处理样式 修改 Windo

WP8.1学习系列(第二十二章)——在页面之间导航

在本文中 先决条件 创建导航应用 Frame 和 Page 类 页面模板中的导航支持 在页面之间传递信息 缓存页面 摘要 后续步骤 相关主题 重要的 API Page Frame NavigationCacheMode 本主题将讨论基本的导航概念,并演示如何创建一个在两个页面之间进行导航的应用. 有关为你的应用选择最佳导航模式的帮助,请参阅导航模式. 在操作时请参阅平面导航和分层导航模式,它们是应用功能大全系列的一部分. 路线图: 本主题与其他主题有何关联?请参阅: 使用 C# 或 Visual

WP8.1学习系列(第十六章)——交互UX之命令模式

命令模式 在本文中 命令类型 命令放置 相关主题 你可以在应用商店应用的几个曲面中放置命令和控件,包括应用画布.弹出窗口.对话框和应用栏.在正确的时间选择合适的曲面可能就是易于使用的应用和很难使用的应用之间的差别. 在应用商店应用中,命令是用户可用来执行操作的交互式 UI 元素.命令与导航元素不同,导航元素用于将用户转移到不同的页面,而命令则可让用户对当前页面执行操作.导航元素使应用可以使用.命令使应用有使用价值. 有关应用中不同命令图面的详细信息,请参阅布置你的 UI. 命令类型 筛选 筛选命

WP8.1学习系列(第二十四章)——Json解析

.net已经集成了json解析,类名叫DataContractJsonSerializer DataContractJsonSerializer 类型公开以下成员. 构造函数   名称 说明 DataContractJsonSerializer(Type) 初始化 DataContractJsonSerializer 类的新实例,以便序列化或反序列化指定类型的对象. DataContractJsonSerializer(Type, IEnumerable<Type>) 初始化 DataCont

【WPF学习】第二十六章 Application类——应用程序的生命周期

原文:[WPF学习]第二十六章 Application类--应用程序的生命周期 在WPF中,应用程序会经历简单的生命周期.在应用程序启动后,将立即创建应用程序对象,在应用程序运行时触发各种应用程序事件,你可以选择监视其中的某些事件.最后,当释放应用程序对象时,应用程序将结束. 一.创建Application对象 使用Application类的最简单方式是手动创建它.下面的示例演示了最小的程序:在应用程序入口(Main()方法)处创建名为MainWindow的窗口,并启动一个新的应用程序: 在本质

【WPF学习】第十九章 控件类

原文:[WPF学习]第十九章 控件类 WPF窗口充满了各种元素,但这些元素中只有一部分是控件.在WPF领域,控件通常被描述为与用户交互的元素--能接收焦点并接受键盘或鼠标输入的元素.明显的例子包括文本框和按钮.然而,这个区别有时有些模糊.将工具提示视为控件,因为它根据用户鼠标的移动显示或消失.将标签视为控件,因为它支持记忆码(mnemonics,将焦点转移到相关控件快捷键). 所有控件都继承自System.Windows.Control类,该类添加了一小部分基本的基础结构: 设置控件内容对齐方式

WP8.1学习系列(第十九章)——事件和路由事件概述

我们将介绍在使用 C#.Visual Basic 或 Visual C++ 组件扩展 (C++/CX) 作为编程语言并使用 XAML 进行 UI 定义时,针对 Windows 运行时应用的事件的编程概念.你可以在 XAML 中的 UI 元素声明中为事件分配处理程序,或者在代码中添加处理程序.Windows 运行时支持路由事件:借助此功能,某些输入事件和数据事件可由引发该事件的对象以外的对象来处理.在定义控件模板或使用页面或版式容器时,路由事件十分有用. 事件即编程概念 通常而言,对 Window

WP8.1学习系列(第十二章)——全景控件Panorama开发指南

2014/6/18 适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1 全景体验是本机 Windows Phone 外观的一部分.与旨在适合手机屏幕边界的标准应用不同,全景应用通过使用超出屏幕边界的长水平画布提供了一个查看控件.数据和服务的独特方式.这些固有的动态视图使用分层动画和内容,以便各层以不同的速度流畅地平移,类似于视差效果. 本主题包括以下部分. 全景控件概述 导航支持 全景应用功能 相关

quick-cocos2d-x 学习系列之十六 塔防完结

quick-cocos2d-x 学习系列之十六 塔防完结 1.  math2d.lua文件 该文件实现了常用的数学函数. Dist函数实现两点的距离. radians4point求两点的夹角(弧度) pointAtCircle求圆上一个点的位置 pointAtLineToPoint求线段上与指定点距离最近的点 degrees2radians角度转换为弧度 radians2degrees弧度转换为角度 2.  utils.lua文件 2.1         drawCircle 返回newCirc