控件模板学习笔记(一)

控件模板定义控件的可视结构和可视行为,通过为控件定义新的控件模板可以更改控件的结构和外观,当创建新的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>
Button的标准控件模板

其中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:这是小女子第一次写博客,欢迎小伙伴们进行批评指正,快来吐槽吧!

posted @ 2015-01-19 16:08  Seesaw  阅读(233)  评论(0编辑  收藏  举报