WPF中的控件模板

WPF包含数据模板和控件模板,其中控件模板又包括ControlTemplate和ItemsPanelTemplate。

其实WPF的每一个控件都有一个默认的模板,该模板描述了控件的外观以及外观对外界刺激所做出的反应。我们可以自定义一个模板来替换掉控件的默认模板以便打造个性化的控件。 

与Style不同,Style只能改变控件的已有属性值(比如颜色字体)来定制控件,但控件模板可以改变控件的内部结构(VisualTree,视觉树)来完成更为复杂的定制。

要替换控件的模板,我们只需要声明一个ControlTemplate对象,并对该ControlTemplate对象做相应的配置,然后将该ControlTemplate对象赋值给控件的Template属性就可以了。

ControlTemplate包含两个重要的属性:

  1. VisualTree,该模板的视觉树,其实我们就是使用这个属性来描述控件的外观的
  2. Triggers,触发器列表,里面包含一些触发器Trigger,我们可以定制这个触发器列表来使控件对外界的刺激发生反应,比如鼠标经过时文本变成粗体等。

代码:

<Button Content="test btn" Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1"  >
WPF中的控件模板        <Button.Template>
WPF中的控件模板          <ControlTemplate>
WPF中的控件模板            <!--
定义视觉树-->
WPF中的控件模板            <Grid>
WPF中的控件模板              <Ellipse Name="faceEllipse" Width="{TemplateBinding Button.Width}" Height="{TemplateBinding Control.Height}"  Fill="{TemplateBinding Button.Background}"/>
WPF中的控件模板              <TextBlock Name="txtBlock" Margin="{TemplateBinding Button.Padding}" VerticalAlignment="Center"  HorizontalAlignment="Center"  Text="{TemplateBinding Button.Content}" />
WPF中的控件模板            </Grid>
WPF中的控件模板            <!--定义视觉树_end-->
WPF中的控件模板            <!--定义触发器-->
WPF中的控件模板            <ControlTemplate.Triggers>
WPF中的控件模板              <Trigger  Property="Button.IsMouseOver"  Value="True">
WPF中的控件模板                <Setter Property="Button.Foreground" Value="Red" />  
WPF中的控件模板              </Trigger>
WPF中的控件模板            </ControlTemplate.Triggers>
WPF中的控件模板            <!--定义触发器_End-->
WPF中的控件模板          </ControlTemplate>
WPF中的控件模板        </Button.Template>
WPF中的控件模板      </Button>

在上面的代码中,修改了Button的Template属性,我们定义了一个ControlTemplate,在<ControlTemplate> ... </ControlTemplate>之间包含的是模板的视觉树,也就是如何显示控件的外观,我们这里使用了一个Ellipse(椭圆)和一个TextBlock(文本块)来定义控件的外观。


界面图:

WPF中的控件模板

在上面的代码中注意到<ControlTemplate.Triggers>... </ControlTemplate.Triggers>之间的部分,我们定义了触发器 

<Trigger  Property="Button.IsMouseOver"  Value="True">,其表示当我们Button的IsMouseIOver属性变成True时,将使用设置器

<Setter Property="Button.Foreground" Value="Red" />  来将Button的Foreground属性设置为Red。这里有一个隐含的意思是:当Button的IsMouseIOver属性变成False时,设置器中设置的属性将回复原值。
代码:

 <Grid ShowGridLines="True">
WPF中的控件模板      <Grid.ColumnDefinitions>
WPF中的控件模板        <ColumnDefinition Width="0.2*"/>
WPF中的控件模板        <ColumnDefinition Width="0.6*"/>
WPF中的控件模板        <ColumnDefinition Width="0.2*"/>
WPF中的控件模板      </Grid.ColumnDefinitions>
WPF中的控件模板      <Grid.RowDefinitions>
WPF中的控件模板        <RowDefinition Height="0.3*"/>
WPF中的控件模板        <RowDefinition Height="0.3*"/>
WPF中的控件模板        <RowDefinition Height="0.4*"/>
WPF中的控件模板      </Grid.RowDefinitions>
WPF中的控件模板      <Button Content="test btn" Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1"  >
WPF中的控件模板        <Button.Template>
WPF中的控件模板          <ControlTemplate>
WPF中的控件模板            <!--
定义视觉树-->
WPF中的控件模板            <Grid>
WPF中的控件模板              <Ellipse Name="faceEllipse" Width="{TemplateBinding Button.Width}" Height="{TemplateBinding Control.Height}"  Fill="{TemplateBinding Button.Background}"/>
WPF中的控件模板              <TextBlock Name="txtBlock" Margin="{TemplateBinding Button.Padding}" VerticalAlignment="Center"  HorizontalAlignment="Center"  Text="{TemplateBinding Button.Content}" />
WPF中的控件模板            </Grid>
WPF中的控件模板            <!--定义视觉树_end-->
WPF中的控件模板            <!--定义触发器-->
WPF中的控件模板            <ControlTemplate.Triggers>
WPF中的控件模板              <Trigger  Property="Button.IsMouseOver"  Value="True">
WPF中的控件模板                <Setter Property="Button.Foreground" Value="Red" />               
WPF中的控件模板              </Trigger>
WPF中的控件模板            </ControlTemplate.Triggers>
WPF中的控件模板            <!--定义触发器_End-->
WPF中的控件模板          </ControlTemplate>
WPF中的控件模板        </Button.Template>
WPF中的控件模板      </Button>
WPF中的控件模板    </Grid>

运行图:

WPF中的控件模板

鼠标移上变色为红色

WPF中的控件模板