现在的位置: 首页 > 综合 > 正文

WPF基础之样式设置和模板化(三)

2013年10月15日 ⁄ 综合 ⁄ 共 2817字 ⁄ 字号 评论关闭

IsItemsHost 属性
在此示例中,一个必需的重要属性是 IsItemsHost 属性。IsItemsHost 属性用于指示在 ItemsControl(如处理项列表的 ListBox 控件)的模板中,生成的元素应放在什么位置。如果将 StackPanel 的这一属性设置为 true,则添加到 ListBox 的所有项都将进入 StackPanel。请注意,此属性只对 Panel 类型有效。

ItemsPresenter 和 ContentPresenter
请注意,如果以这种方式在 ControlTemplate 中指定一个面板并将其标记为 IsItemsHost,控件的用户不使用 ControlTemplate 就无法替换 ItemsPanel。因此,除非您确信必须使用模板才能替换面板,否则不要采用这种方式。此外,您也可以使用 ItemsPresenter 元素来标记项的位置,然后通过设置 ItemsPanel 属性来指定 ItemsPanelTemplate。ItemsPanelTemplate 页提供了一个示例,为您演示如何操作。

如果要创建 ContentControl(如 Button)的模板,则对应元素为 ContentPresenter。同样,将此元素放置到 ContentControl 类型的 ControlTemplate 中,可以指示内容应在什么位置显示,如什么是 ControlTemplate? 一节中的示例所示。有关其他示例,请参见 Label ControlTemplate 示例和 ListBoxItem ControlTemplate 示例。

TemplateBinding
在上一示例中,需要注意的另一个重点是设置为 {TemplateBinding ListBox.Background} 的 Background 值。它只是指示 Border 的 Background 应与 ListBox 上设置的 Background 值同步。TemplatBinding 与 Binding 类似。实际上,TemplatBinding 比 Binding 更有效,但功能更弱;使用 TemplatBinding 等效于使用 Source 属性设置为 RelativeSource.TemplatedParent 的 Binding。

若要使控件用户能够控制某些属性的值,可以在 ControlTemplate 中使用 TemplateBinding。TemplateBinding 是一个由 TemplateBindingExtension 类表示的标记扩展。

您可能已经注意到,DataTemplate 和 ControlTemplate 的相似之处在于它们的内容变成了对象的外观。通过 ListBox ControlTemplate 定义,应用程序现在的外观如下:


Style、ControlTemplate 和 DataTemplate 都具有 Triggers 属性,该熟悉可以包含一组触发器。某个属性值更改时,或某个事件引发时,触发器会相应地设置属性或启动操作(如动画操作)。

触发器

属性触发器
为了演示如何使用触发器来设置属性,我们将每个 ListBoxItem 都设置为部分透明(除非它被选中)。

下面的样式将 ListBoxItem 的 Opacity 值设置为 0.5。但是,当 IsSelected 属性为 true 时,Opacity 设置为 1.0:

 

此示例使用 Trigger 来设置属性值,但请注意,Trigger 类还具有 EnterActions 和 ExitActions 属性,通过这两个属性,触发器可以执行操作。

请注意,我们还将 ListBoxItem 的 MaxHeight 属性设置为 75。在下面的屏幕快照中,选中的项是第三项:

 

EventTrigger 和 Storyboard
我们刚刚演示了 Trigger 根据某个属性的值来设置属性值或启动操作。另一种类型的触发器是 EventTrigger,它根据事件的引发来启动一组操作。例如,下面的 EventTrigger 对象指定当鼠标指针进入 ListBoxItem 时,MaxHeight 属性在 0.2 秒时间内以动画方式增大为值 90。当鼠标离开该项时,该属性在 1 秒时间内还原为原始值。请注意为何无需为 MouseLeave 动画指定 To 值。这是因为动画能够跟踪原始值。

 

在下面的屏幕快照中,鼠标指向第三项:

MultiTrigger、DataTrigger 和 MultiDataTrigger
除了 Trigger 和 EventTrigger 之外,还有其他类型的触发器。通过 MultiTrigger,可以根据多个条件来设置属性值。如果条件的属性是经过数据绑定的,则可以使用 DataTrigger 和 MultiDataTrigger。

共享的资源和主题
典型 Windows Presentation Foundation (WPF) 应用程序可能具有多个在整个应用程序范围内应用的用户界面 (UI) 资源。概括地说,这组资源可视为应用程序的主题。通过使用封装为 ResourceDictionary 类的资源字典,Windows Presentation Foundation (WPF) 支持将用户界面 (UI) 资源打包为主题。

Windows Presentation Foundation (WPF) 主题是使用样式设置和模板化机制定义的,Windows Presentation Foundation (WPF) 公开该机制,用于自定义任何元素的可视对象。

Windows Presentation Foundation (WPF) 主题资源存储在嵌入式资源字典中。这些资源字典必须嵌入到已签名的程序集中,它们既可以嵌入到代码自身所在的程序集中,也可以嵌入到并行程序集中。对于包含 Windows Presentation Foundation (WPF) 控件的程序集 PresentationFramework.dll,主题资源在一系列并行程序集中。

搜索元素样式时,主题是最后查找的位置。通常,搜索首先沿元素树向上查找相应资源,然后在应用程序资源集合中查找,最后查询系统。这为应用程序的作者提供了机会,让他们可以在到达主题之前,在树或应用程序级重新定义任何对象的样式。

您可以将各资源字典分别定义为单个文件,这样就可以在多个应用程序中重用某个主题。通过定义多个提供相同类型资源、但具有不同值的资源字典,也可以创建可交换的主题。在设计应用程序外观时,建议在应用程序级重新定义这些样式或其他资源。

若要在多个应用程序中共享一组资源(包括样式和模板),可以创建一个 XAML 文件并定义一个 ResourceDictionary。例如,请看下面的屏幕快照,它显示了使用 ControlTemplates 设置样式的示例的一部分:

如果查看示例中的 XAML 文件,您会注意到所有文件都包含以下内容:

 

这是共享的 shared.xaml,该文件定义一个 ResourceDictionary,该资源字典包含一组样式和画笔资源,使示例中的控件具有了一致的外观。

抱歉!评论已关闭.