翼度科技»论坛 编程开发 .net 查看内容

浅谈WPF之各种Template

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
前几天写了一篇文章【浅谈WPF之控件模板和数据模板】,有粉丝反馈说这两种模板容易弄混,不知道什么时候该用控件模块,什么时候该用数据模板,以及template和itemtemplate之间的关系等,今天专门写一篇文章,简述WPF中各种模板及其相互关系。仅供学习分享使用,如有不足之处,还请指正。

 
概述

在WPF中,一共有三种模板,分别如下:

  • 控件模板ControlTemplate,用来指定控件的呈现样式。
  • 数据模板DataTemplate,用来指定子项数据的呈现样式。
  • 子控件模板ItemPanelTemplate,用来指定子项控件的布局样式。
 
模板与控件之间的关系

 
关于各个模板与控件之间的关系,如下图所示:

通过上图可以看出:

  • Control拥有Template属性,是ControlTemplate类型,所有Control派生的子控件,都具有Template属性,都可以通过控件模板设置控件的样式。
  • ContentControl拥有ContentTemplate属性,是DataTemplate类型,所有ContentControl派生的控件,都具有ContentTemplate属性,如Button,ListBoxItem,DataGridCell等。
  • ItemsControl拥有ItemsTemplate属性,是DataTemplate类型,所有ItemsControl派生的控件,都具有ItemsTemplate属性,如ListBox,ComboBox,DataGrid,ListView等。
  • ItemsControl拥有ItemsPanel属性,是ItemsPanelTemplate类型,所有ItemsControl派生的控件,都具有ItemsPanel属性,如ListBox,ComboBox,DataGrid,ListView等。
  • Template,ContentTemplate,ItemsTemplate,ItemsPanel只是属性名称,而DataTemlate,ControlTemplate,ItemsPanelTemplate才是模板类型。
 
ControlTemplate控件模板详解

 
利用ControlTemplate可以彻底的颠覆控件的默认外观。里面的内容就是视觉树VisualTree。
两个重要属性:
a)ContentPresenter

重定义控件模板,默认模板将会被覆盖,此时需要利用ContentPresenter,把原有模板的属性原封不动的投放到自定义模板中。
b)Triggers

触发器列表,里面包含一些触发器Trigger,我们可以定制这个触发器列表来使控件对外界的刺激发生反应,比如鼠标经过时文本变成粗体等。
控件模板示例
  1. <Window x:
  2.          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.          xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5.          Title="MainWindow" Height="350" Width="525">
  6.     <Window.Resources>
  7.         <ControlTemplate x:Key="rect" TargetType="{x:Type CheckBox}">
  8.             <ControlTemplate.Resources>
  9.                 <SolidColorBrush x:Key="redBrush" Color="Red"/>
  10.             </ControlTemplate.Resources>
  11.             <StackPanel>
  12.                 <Rectangle Name="breakRectangle" Stroke="Red" StrokeThickness="2" Width="20" Height="20">
  13.                     <Rectangle.Fill>
  14.                         <SolidColorBrush Color="White"/>
  15.                     </Rectangle.Fill>
  16.                 </Rectangle>
  17.                 <ContentPresenter/>
  18.             </StackPanel>
  19.             <ControlTemplate.Triggers>
  20.                 <Trigger Property="IsChecked" Value="True">
  21.                     <Setter TargetName="breakRectangle" Property="Fill" Value="{StaticResource ResourceKey=redBrush}">
  22.                     </Setter>
  23.                 </Trigger>
  24.             </ControlTemplate.Triggers>
  25.         </ControlTemplate>
  26.     </Window.Resources>
  27.     <Canvas>
  28.         <CheckBox Template="{StaticResource ResourceKey=rect}"  Content="我是CheckBox"/>
  29.     </Canvas>
  30. </Window>
复制代码
注意: 实现了将模板中的Margin绑定到原控件中的Padding上去。
将控件模板写到样式里面,如下所示:
  1. [/code]通过绑定样式资源,如下所示:
  2. [code]
复制代码
 
c)ItemsPresenter

 

继承自ItemsControl的控件,有一个ItemsPanel属性作为集合元素承载容器。子元素ItemsPresenter负责呈现控件的任务。

只要把ItemsPresenter放在内部模板中,那么ItemsPresenter则会去检测父元素是否为集合控件,然后将ItemsPanel添加到其内部视觉树当中。
  1. [/code]比较常见的继承自ItemsControl的控件,比如ComboBox,ContextMenu,ListBox,DataGrid,ListView等。
  2.  
  3. [size=6][b]DataTemplate数据模板详解[/b][/size]
  4.  
  5. 数据模板定义了数据的显示方式,也就是数据对象的可视结构。主要是可以自定义控件的同时进行数据绑定。
  6. [code]<Window x:
  7.          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  8.          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  9.          xmlns:sys="clr-namespace:System;assembly=mscorlib"
  10.         xmlns:src="clr-namespace:WpfApplication1"
  11.          Title="MainWindow" Height="350" Width="525">
  12.     <Window.Resources>
  13.         <ObjectDataProvider x:Key="personList" ObjectType="{x:Type src:PersonList}"/>
  14.         <DataTemplate x:Key="rect">
  15.             <Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
  16.                 <StackPanel>
  17.                     <StackPanel Orientation="Horizontal">
  18.                         <TextBlock Text="{Binding Name}" Margin="5,0,0,0"/>
  19.                         <TextBlock Text="{Binding Age}" Margin="5,0,0,0"/>
  20.                     </StackPanel>
  21.                     <StackPanel Orientation="Horizontal">
  22.                         <TextBlock Text="{Binding Address}" Margin="5,0,0,0"/>
  23.                     </StackPanel>
  24.                 </StackPanel>
  25.             </Border>
  26.         </DataTemplate>
  27.     </Window.Resources>
  28.     <Grid>
  29.         <ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=personList}}"
  30.                   ItemTemplate="{StaticResource ResourceKey=rect}"></ListBox>
  31.     </Grid>
  32. </Window>
复制代码
注意这里在调用时应该绑定的是 ItemTemplate 属性。 
 
ItemPanelTemplate详解

 
首先我们要知道常见的条目控件有:ListBox,Menu,StatusBar等。
比如拿ListBox来说,ItemBox的ItemPanel其实是一个VisualizingStackPanel,就是说ListBox的每一项的排列方式是遵循StackPanel的
原则,也就是从上到下的排列方式。如果要实现从左到右排列:
  1. <Window x:
  2.          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.          xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5.         xmlns:src="clr-namespace:WpfApplication1"
  6.          Title="MainWindow" Height="350" Width="525">
  7.     <Window.Resources>
  8.         <ObjectDataProvider x:Key="personList" ObjectType="{x:Type src:PersonList}"/>
  9.         <DataTemplate x:Key="rect">
  10.             <Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
  11.                 <StackPanel>
  12.                     <StackPanel Orientation="Horizontal">
  13.                         <TextBlock Text="{Binding Name}" Margin="5,0,0,0"/>
  14.                         <TextBlock Text="{Binding Age}" Margin="5,0,0,0"/>
  15.                     </StackPanel>
  16.                     <StackPanel Orientation="Horizontal">
  17.                         <TextBlock Text="{Binding Address}" Margin="5,0,0,0"/>
  18.                     </StackPanel>
  19.                 </StackPanel>
  20.             </Border>
  21.         </DataTemplate>
  22.     </Window.Resources>
  23.     <Grid>
  24.         <ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=personList}}"
  25.                   ItemTemplate="{StaticResource ResourceKey=rect}"></ListBox>
  26.     </Grid>
  27. </Window>                           
复制代码
也就是说,ItemsPanelTemplate可以用来定义集合控件的容器外观。
 
总结

 
1、Template


控件模板,是指整个控件的展示和布局。
如ComboBox,可分为文本区域,下拉按钮区域,Items的Popup区域。
Template就是管理这些位置的布局。
2、ItemsPresenter


可以简单理解为占位符,在样式中使用,标记着这个区域用来展示该控件的Items。
如:ComboBox的下拉列表的可选项。
但是,只负责显示,而不能管理如何显示,如果我们要内容横向排列,就要用到ItemsPanel。
3、ItemsPanel


管理Items的排列方式,如,ComboBox默认是竖直排列的,我们要横着排列,只需要定义ItemsPanel为WrapPanel,就可以了。
这时候Items的排列方式已经完成,如果还要让ComboBox的每个项都重写,比如,背景、图标等,就要用到ItemContainerStyle。
4、ItemContainerStyle


就是每个项的样式,自己重写,就可以定制出每个项的样式了。
以上就是浅谈WPF之各种模板的全部内容。

来源:https://www.cnblogs.com/hsiang/archive/2023/11/22/17845333.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具