WPF 控件模板

WPF中每个控件都被设计为无外观的,这意味着我们可以通过一定的方式,完全重定义其可视化外观,而WPF也提供了这种改变外观的方式之一,我们称为模板。wpf的模板有多种方式,可以分为控件模板(ControlTemplate),控件列表模板(ItemsPanelTemplate)和数据模板(DataTemplate)。其中ControlTemplate和ItemsPanelTemplate都属于控件模板,但又有不同的表示。

1、控件模板(ControlTemplate)

理解控件模板,首先得理解两个概念逻辑树和可视化树,逻辑树是我们最基本的要素列表,可视化树是逻辑书的扩展版本,它将元素分为更小的部分。换句话说说,逻辑树仅仅关心到控件级别,而可视化树关心到控件的组成的最基本图形元素。

1.1 定义模板样式

每个控件都有一个内置的方法,用于确定如何渲染控件,该方法称为控件模板,可以使用XAML标记块定义,下面我们定义一个普通的按钮的模板:

<Button x:Name="btn1" Click="Button_Click" >
         <Button.Template >
             <ControlTemplate >
                 <Grid >
                     <Ellipse Name="faceEllipse" Height="50" Width="100" Fill="{TemplateBinding Button.Background}"/>
                     <TextBlock Name="txtBlock"  Text="text" VerticalAlignment="Center" HorizontalAlignment="Center" />
                 </Grid >
             </ControlTemplate >
         </Button.Template>
     </Button>

效果如下:

image

模板是控件的Template 属性,Template 是一个ControlTemplate对象,我们可以重定义这个对象,就是重新定义了按钮的界面,ControlTemplate里面可以使用任何控件,比如以下代码:

<Button x:Name="btn1" Click="Button_Click" >
        <Button.Template >
            <ControlTemplate >
                <Grid >
                    <Ellipse Name="faceEllipse" Height="50" Width="100" Fill="{TemplateBinding Button.Background}"/>
                    <TextBlock Name="txtBlock"  Text="text" VerticalAlignment="Center" HorizontalAlignment="Center" />
                    <CheckBox  IsChecked="True"></CheckBox>
                </Grid >
            </ControlTemplate >
        </Button.Template>
    </Button>

其效果如下:

image

不过这种做法不常见,使用的时候需要谨慎处理。

1.2 模板触发器

  触器是模板里面一个常用的功能,能为当前控件提供显示的多样性和多状态提供的触发机制,比如按钮,鼠标移上和鼠标移开,获取焦点和非焦点,都不一样,这些在不同状态下的显示,就需要触发器完成,触发器的详细讲解,请查看http://www.cnblogs.com/minhost/p/7464148.html。控件模板触发器,基本能触发常规的触发器,属性和事件等。我们看看触发器如何使用:

<Button x:Name="btn1" Click="Button_Click" >
         <Button.Template >
             <ControlTemplate >
                 <Grid >
                     <Ellipse Name="faceEllipse" Height="50" Width="100" Fill="{TemplateBinding Button.Background}"/>
                     <TextBlock Name="txtBlock"  Text="text" VerticalAlignment="Center" HorizontalAlignment="Center" />
                 </Grid >
                 <ControlTemplate.Triggers >
                     <Trigger Property="Button.IsMouseOver" Value="True">
                         <Setter Property="Button.Background" Value="blue"/>
                     </Trigger >
                 </ControlTemplate.Triggers >
             </ControlTemplate >
    
         </Button.Template>
     </Button>

以上触发器,就是当前鼠标经过的时候,让按钮的背景变为蓝色,可以看到效果如下:

image

1.3 模板的复用

我们上面的案例,只是把模板放在按钮内部,那么只有这个按钮才能使用,为了实现共享模板等,我们可以把模板定义在resource里面,所以我们完全可以把以上代码添加到window.resource中,如以下代码:

<Window.Resources>
      <ControlTemplate  x:Key="btntemp">
          <Grid >
              <Ellipse Name="faceEllipse" Height="50" Width="100" Fill="{TemplateBinding Button.Background}"/>
              <TextBlock Name="txtBlock"  Text="text" VerticalAlignment="Center" HorizontalAlignment="Center" />
          </Grid >
          <ControlTemplate.Triggers >
              <Trigger Property="Button.IsMouseOver" Value="True">
                  <Setter Property="Button.Background" Value="blue"/>
              </Trigger >
          </ControlTemplate.Triggers >
      </ControlTemplate >
  </Window.Resources>
  <Canvas>
      <Button x:Name="btn1" Click="Button_Click" Template="{StaticResource btntemp}"></Button>
  </Canvas>

能实现以上相同功能,假如有多个按钮的话,则可以对模板进行复用,如果我们想当前窗体所有的按钮都统一样式,则可以指定 <ControlTemplate  x:Key="btntemp" TargetType="Button">,那么界面上所有的按钮(除非特别指定)都会使用当前样式。

 

posted @ 2017-09-27 10:50  Min.Xiaoshuang  阅读(2120)  评论(0编辑  收藏  举报