avatar

目錄
WPF学习笔记(三)WPF模板

WPF学习笔记(三)WPF模板

WPF模板其实都是外观的表现形式,不管是控件模板、数据模板还是面板模板,其都是改变控件的表现形式。只不过这三种控件的作用点不一样罢了。

控件模板是针对于控件本身,修改它可以改变控件本身表现的样子;

数据模板针对控件的数据,修改它可以改变控件绑定的数据表现样子。既然是决定数据的表现,从而决定其一般应用于数据绑定控件,如ListBox、ListView等控件。

面板模板则针对于控件的布局,修改它可以影响控件的布局方式。

一、控件模板

1. 控件模板与Style的异同

都是为了实现空间的个性化。

Style只能改变控件已有的属性(比如字体颜色等),但控件模板可以改变空间的内部结构(VisualTree,视觉树)来完成更为复杂的定制,比如我们可以定制一个带图片的按钮。

2. 通过控件模板自定义控件外观

WPF中每一个控件都有一个默认的模板,该模板描述了空间的外观以及外观对外界刺激所做出的反应;

我们也可以自定义一个模板来替换控件默认模板以便打造个性化的控件。

示例:制作一个圆形的按钮,当鼠标移入按钮后,会通过触发器使按钮背景变为红色

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 <!--定义控件模板,并用key标记-->
<ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
<Grid>
<Ellipse x:Name="ell" Fill="Orange" Height="100" Width="100" />
<!--使用模板绑定来绑定按钮的内容-->
<ContentPresenter Content="{TemplateBinding Button.Content}" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>

<!--定义模板触发器-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ell" Property="Fill" Value="Red" />
<Setter Property="FontSize" Value="30" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<!--引用-->
<Button Grid.Row="1" Name="btn2"
Content="WPF"
Template="{StaticResource ButtonTemplate}">
</Button>

效果如下所示:

使用控件模板非常简单:

  • 首先在资源集合中创建一个ControlTemplate,并指定key标记
  • 然后赋值到控件的Template属性中

二、数据模板

1. 有两种类型的控件支持数据模板

  • 内容控件通过ContentTemplate属性支持数据模板。内容模板用于显示任何放在Content属性中的内容。
  • 列表控件,即继承自ItemsControl类的控件,通过ItemPlate属性支持数据模板。该模板用于显示由ItemSource提供集合中的每一项。

2. 常用控件的三种类型

如下图所示:

类型

  1. Grid这种列表表格中修改Cell的数据格式, CellTemplate可以修改单元格的展示数据的方式。
  2. 针对列表类型的控件, 例如树形控件,下拉列表,列表控件, 可以修改其中的ItemTemplate。
  3. 修改ContentTemplate, 例UserControl控件的数据展现形式。

2.1 CellTemplate 模板

示例:实现一个DataGrid 展示一个普通的数据表, 同时新增一列CellTemplate添加两个自定义的按钮。代码如下:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Grid>
<DataGrid Name="gd" AutoGenerateColumns="False" CanUserSortColumns="True" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding UserName}" Width="100" Header="学生姓名"/>
<DataGridTextColumn Binding="{Binding ClassName}" Width="100" Header="班级名称"/>
<DataGridTextColumn Binding="{Binding Address}" Width="200" Header="地址"/>
<DataGridTemplateColumn Header="操作" Width="100" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<Button Content="编辑"/>
<Button Margin="8 0 0 0" Content="删除" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>

在后台构造函数中进行该DataGrid进行数据绑定:

c#
1
2
3
4
5
6
7
List<Student> students = new List<Student>();

students.Add(new Student() { UserName = "小王", ClassName = "高二三班", Address = "广州市" });
students.Add(new Student() { UserName = "小李", ClassName = "高三六班", Address = "清远市" });
students.Add(new Student() { UserName = "小张", ClassName = "高一一班", Address = "深圳市" });
students.Add(new Student() { UserName = "小黑", ClassName = "高一三班", Address = "赣州市" });
gd.ItemsSource = students;

最终的效果, 在数据表格的最后一列, 将会在一列中分别生成 两个普通按钮:

2.2 ItemTemplate 模板

在列表的控件中, 常常会出现一些需求, 类似在下拉控件或树控件中添加一个 CheckBox选择框, 一个图标或图片, 这个时候, 我们就可以利用自定义的DataTemplate 来实现这个功能,

该示例来简单演示其功能, 利用 ListBox 和 ComboBox来绑定一个颜色代码列表, 同时展示其颜色。

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Page.Resources>
<DataTemplate x:Key="comTemplate">
<StackPanel Orientation="Horizontal" Margin="5,0">
<Border Width="10" Height="10" Background="{Binding Code}"/>
<TextBlock Text="{Binding Code}" Margin="5,0"/>
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<ComboBox Name="cob" Width="120" Height="30" ItemTemplate="{StaticResource comTemplate}"/>
<ListBox Name="lib" Width="120" Height="100" Margin="5,0"
ItemTemplate="{StaticResource comTemplate}"/>
</StackPanel>
</Grid>

后台绑定代码如下:

c#
1
2
3
4
5
6
7
8
9
10
List<Color> ColorList = new List<Color>();
ColorList.Add(new Color() { Code = "#FF8C00" });
ColorList.Add(new Color() { Code = "#FF7F50" });
ColorList.Add(new Color() { Code = "#FF6EB4" });
ColorList.Add(new Color() { Code = "#FF4500" });
ColorList.Add(new Color() { Code = "#FF3030" });
ColorList.Add(new Color() { Code = "#CD5B45" });

cob.ItemsSource = ColorList;
lib.ItemsSource = ColorList;

最终测试效果如下:

2.3 ItemsControl

定义ItemsControl 主要分两个步骤:

  1. 设置ItemsPanel容器, 用于容纳列表的最外层容器
  2. 定义子项的DataTemplate

示例代码:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
<ItemsControl Name="ic">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--ItemsControl的数据模板-->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="50" Height="50" Content="{Binding Code}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

最终效果:

通过以上示例可知,使用DataTemplate很简单:

  • 首先在资源集合中创建一个数据模板,并设置key标签。
  • 然后将key赋值到控件的CellTemplate或ContentTemplate或ItemTemplate属性上即可。

3. 数据模板与控件模板的关系

控件只是数据和行为的载体,至于它本身长什么样子和数据长什么样子都是靠Template决定的。决定控件外观的是ControlTemplate,决定数据外观的是DataTemplate,它们正是Control类的Template和ContentTemplate两个属性的值。

一般来说,ControlTemplate内都有一个ContentPresenter,这个ContentPresenter的ContentTemplate就是DataTemplate类型。

三、面板模板

ItemsPanelTemplate用于指定项的布局。 ItemsControl 类型具有一个类型为ItemsPanelTemplate 的 ItemsPanel 属性。

示例,部分代码如下:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<Grid Grid.Row="2">
<ItemsControl ItemsSource="{Binding MenuModels}">
<!--创建面板模板-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--数据模板-->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border CornerRadius="3" Margin="40 2 40 0" Background="White" Height="50">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>

<TextBlock Text="⚪" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="123456" />
<TextBlock Text="任务" />
</StackPanel>
<TextBlock Grid.Column="2" Text="☆" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>

最终效果:

四、总结…

WPF模板的内容就简单的了解到这儿,使用这些模板的方式都是先定义一个模板,然后在把对应的key应用到控件对应的属性中。对于控件模板,应用的是控件的Template;对于数据模板,应用的是控件的ItemTemplate属性;对于面板模板,应用的是控件的ItemsPanel属性

参考链接

文章作者: Dylan
文章鏈接: https://www.faithlch.com/WPF%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E4%B8%89-WPF%E6%A8%A1%E6%9D%BF.html
版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Dylan He
打賞
  • 微信
    微信
  • 支付寶
    支付寶

評論