控件模板定义控件的可视结构和可视行为,通过为控件定义新的控件模板可以更改控件的结构和外观,当创建新的ControlTemplate时,将替换现有控件的外观,而无需更改其功能。例如,可以将应用程序中的按钮设置为不是默认的方形,
但是,依旧还是会引发Click事件。那么问题来了,控件模板包含什么,怎么去定义全新的控件模板
1.控件模板包含什么
下面就剖析一个简单的控件Button来看一下Button的标准控件模板包含什么
剖析出来的结果如下:
<?xml version="1.0" encoding="utf-16"?> <ControlTemplate TargetType="ButtonBase" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Border BorderThickness="{TemplateBinding Border.BorderThickness}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="border" SnapsToDevicePixels="True"> <ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Name="contentPresenter" Margin="{TemplateBinding Control.Padding}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Focusable="False" /> </Border> <ControlTemplate.Triggers> <Trigger Property="Button.IsDefaulted"> <Setter Property="Border.BorderBrush" TargetName="border"> <Setter.Value> <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="UIElement.IsMouseOver"> <Setter Property="Panel.Background" TargetName="border"> <Setter.Value> <SolidColorBrush>#FFBEE6FD</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush" TargetName="border"> <Setter.Value> <SolidColorBrush>#FF3C7FB1</SolidColorBrush> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="ButtonBase.IsPressed"> <Setter Property="Panel.Background" TargetName="border"> <Setter.Value> <SolidColorBrush>#FFC4E5F6</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush" TargetName="border"> <Setter.Value> <SolidColorBrush>#FF2C628B</SolidColorBrush> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="ToggleButton.IsChecked"> <Setter Property="Panel.Background" TargetName="border"> <Setter.Value> <SolidColorBrush>#FFBCDDEE</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush" TargetName="border"> <Setter.Value> <SolidColorBrush>#FF245A83</SolidColorBrush> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="UIElement.IsEnabled"> <Setter Property="Panel.Background" TargetName="border"> <Setter.Value> <SolidColorBrush>#FFF4F4F4</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush" TargetName="border"> <Setter.Value> <SolidColorBrush>#FFADB2B5</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="TextElement.Foreground" TargetName="contentPresenter"> <Setter.Value> <SolidColorBrush>#FF838383</SolidColorBrush> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>False</s:Boolean> </Trigger.Value> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
其中Border定义了Button的边框,ContentPresenter显示按钮的内容,Triggers(触发器)指定按钮的属性变化相应。几个特殊属性的含义,RecognizesAccessKey属性设置为True可确保按钮支持访问健,可以使用该字母快速触发按钮,
SnapsToDevicePixels=“True”确保单个像素的线条不会根据WPF分辨率的不同被放在两个像素”中间“(导致模糊的双像素线条)。
2.创建新的ControlTemplate
首先看一下Button的标准外观 ,当鼠标放上去的外观,当鼠标点击后的外观
接下来开始创建控件模板,第一步为Button的标准外观创建模板,其中添加了一个Rectangle更改的Button的可视化结构
<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}"> <Border Name="Border" BorderBrush="Orange" BorderThickness="3" CornerRadius="2" Background="Red" TextBlock.Foreground="White" SnapsToDevicePixels="True"> <Grid> <Rectangle Name="FocusCue" Visibility="Hidden" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2" SnapsToDevicePixels="True"></Rectangle> <ContentPresenter RecognizesAccessKey="True" Margin="{TemplateBinding Padding}"></ContentPresenter> </Grid> </Border> </ControlTemplate>
效果如图:,但是挡在它上面移动鼠标或是点击鼠标时,其外观没有反应。
然后通过设置ControlTemplate.Triggers来设置Button属性改变所做的相应
<ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="Border" Property="Background" Value="DarkRed" /> </Trigger> <Trigger Property="IsPressed" Value="true"> <Setter TargetName="Border" Property="Background" Value="IndianRed" /> <Setter TargetName="Border" Property="BorderBrush" Value="DarkKhaki" /> </Trigger> <Trigger Property="IsKeyboardFocused" Value="True"> <Setter TargetName="FocusCue" Property="Visibility" Value="Visible" /> </Trigger> </ControlTemplate.Triggers>
当鼠标滑过Button时,背景颜色变为DarkRed;当鼠标点击Button时,背景颜色变为IndianRed;当Button获取焦点时,FocusCue为可见。其中IsMouseOver,IsPressed,IsKeyboardFocused是Button的内置属性
这只是实现了一个简单鼠标的自定义模板,接下来我会进一步更新学习WPF模板的历程和心得,敬请期待
ps:这是小女子第一次写博客,欢迎小伙伴们进行批评指正,快来吐槽吧!