一、控件模板概述
控件的外观通过一个ControlTemplate类型的对象确定,该对象指定了组成一个控件的显示的各种视觉元素。
当WPF创建一个控件时,会创建一个控件类(模板父)的实例,然后实例化通过它的ControlTemplate设定的这个控件的外观树(组成这个控件的内部UI元素)。
二、开发自定义的简单控件模板
为了简单起见,我们开发一个简单的Button控件模板。步骤参见以下:
1)在Window的Resources中定义一个名字为myButtonTemplate的控件模板
2)在使用StaticResource标记扩展为Button的Template属性赋值
至此,一个简单的Button的ControlTemplate就算开发好了,但是仔细看图,我们会发现一个问题,我们按钮实际显示的文本信息与我们设定的文本信息是不一致的,这不是我们的预期,就连背景色和Border的颜色也不是我们的预设值,而是使用了模板的默认值,那么我们该如何修改控件模板来达到我们的预期呢?
三、控件模板之TemplateBinding
为了达到上述预期的效果,我们可以使用TemplateBinding将控件模板中的属性绑定到控件本身(模板父)。参见以下代码:
从图中可以看出,现在已经达到了预期的效果。
为了达到上述同样显示文本的效果,我们也可以使用ContentPresenter。
四、ContentPresenter对象
1)ContentPresenter作为一个占位符,用来在模板中指定Content应该放置的位置;
2)默认情况下,ContentPresenter从模板父(应用控件模板的控件本身)获取实际的内容,然后绑定到自己的Content属性;
3)为了使用ContentPresenter,我们需要设置ControlTemplate的TargetType属性为模板父的类型。
使用了ContentPresenter的ControlTemplate参见以下:
五、触发器
1)Trigger必须在ControlTemplate.Triggers的节点下;
2)Triggers集合中可以包含任意数量的Trigger;
3)一个Trigger可以有任意数量的Setter;
4)每个Setter中指定三个属性,分别是TargetName、Property和Value。
带有触发器的控件模板参见以下:
当鼠标移动到按钮上面的时候,按钮和Border和背景色会变成模板中预设的样式。
附录:代码

1 <Window x:Class="ControlTemplateDemo1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:ControlTemplateDemo1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="350" Width="525"> 9 <Window.Resources> 10 <ControlTemplate x:Key="myButtonTemplate" TargetType="Button"> 11 <Border Background="{TemplateBinding Background}" 12 BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderBrush}" 13 BorderThickness="1" CornerRadius="3" Name="border"> 14 <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/> 15 </Border> 16 <ControlTemplate.Triggers> 17 <Trigger Property="IsMouseOver" Value="True"> 18 <Setter Property="BorderBrush" Value="Red" TargetName="border"/> 19 <Setter Property="Background" Value="Silver" TargetName="border"/> 20 </Trigger> 21 </ControlTemplate.Triggers> 22 23 </ControlTemplate> 24 </Window.Resources> 25 <Grid> 26 <Button Content="Button" Background="Pink" BorderBrush="Green" 27 Template="{StaticResource myButtonTemplate}" Width="60" Height="30" > 28 </Button> 29 </Grid> 30 </Window>