WPF 控件模板

1.控件模板和style的区别

 Style用来修改控件属性的值,比如button的height width background。

Controltemplate用来修改一个控件的内部结构,比如一个button,想把一个button的内部添加一个图片和一个提示文本,这两部分合起来还能完成button的功能

一个细节,默认让所有的目标类型引用控件模板,定义在一个style中,因为style不写key,是默认所有的目标类型的控件自动引用的

2.定义ControlTemplate的方法

2.1定义在控件内部

<Button Height="100" Width="100">
     <Button.Template>
         <ControlTemplate>
              <Border BorderBrush="Red" BorderThickness="1">
                   <StackPanel>
                        <TextBlock Text="喜羊羊" HorizontalAlignment="Center"/>
                        <Image Source="xyy.jpg"/>
                   </StackPanel>
              </Border>
         </ControlTemplate>
      </Button.Template>
 </Button>

这种方式定义的controltemplate只能给这一个button用。

2.2为了可复用,定义在资源中,也可定义在资源字典中

<Window.Resources>
  <ControlTemplate TargetType="Button" x:Key="MyButtonControltemplate">
    <Border BorderBrush="Red" BorderThickness="1">
      <StackPanel>
        <TextBlock Text="喜羊羊" HorizontalAlignment="Center"/>
        <Image Source="xyy.jpg"/>
       </StackPanel>
    </Border>
  </ControlTemplate>
</Window.Resources>

xaml中button引用控件模板

<Button Height="100" Width="100" Template="{StaticResource MyButtonControltemplate}" />

运行结果:

 控件模板中,添加了一个textblock和一个image,这个就是修改了控件模板的内部结构,在标签<ControlTemplate>中包含的部分就是内部结构的布局。 

一个ControlTemplate的内部可分为2部分,一个是控件的新布局,一个是处理触发器

3.几个关键字的解释

3.1 TargetType:

指定所定义的ControlTemplate会被那种类型的控件引用

3.2 x:Key: 

 ControlTemplate的名字,比如是 MyButtonControltemplate

在控件引用时使用 Template="{StaticResource MyButtonControltemplate}" 

 3.3 templatebinding

该关键字在控件模板内部使用,目的是为了让控件模板中的某些属性非固定写死的,而是控件模板外部的某些属性关联起来,也就是绑定起来。

举个例子,如上面的例子,图片中的“喜羊羊”字符串是在ControlTemplate中使用一个TextBlock的Text属性写好的,当button使用这个Controltemplate时,无法修改这个字符串,假如我们想让Textblock的text随着button的Content属性改变而改变,这是需要做一些改动:

ControlTemplate:

 Xaml代码:

 运行结果

 如果有2个button,都引用了这个控件模板,则2个button互不影响。

 4.ControlTemplate的Triggers和Eventtrigger

触发器有很多种Trigger、DataTrigger、EventTrigger,MultiTrigger,MultiDataTrigger

4.1针对属性的值做判断的Trigger

Trigger当什么条件成立时,执行什么操作,是针对属性的值,是引用该控件模板的控件的属性,所以可以判断任何一个属性的值

比如当鼠标进入控件时,执行什么操作

比如当Button的Conten属性是什么值时执行什么操作

比如当Button的height属性是多少时,执行什么操作

<ControlTemplate.Triggers>
  <Trigger Property="Content" Value="123">    <Setter Property="TextBlock.Text" Value="123+1" TargetName="textblock"/> </Trigger>   <Trigger Property="Height" Value="100">   <Setter Property="TextBlock.Text" Value="Button的height是100" TargetName="textblock"/>   </Trigger>
<ControlTemplate.Triggers>

需要注意的是:<ControlTemplate.Triggers></ControlTemplate.Triggers>标签内可以添加多个rigger,如果2个trigger对同一个属性做了操作,则后写的trigger会覆盖先写的trigger

4.2EventTrigger是针对对象的事件,当发生哪个事件时执行什么操作

<EventTrigger RoutedEvent="Button.MouseDoubleClick">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard >
                            <ColorAnimation Storyboard.TargetName="textblock" 
                                            Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                           To="Blue" Duration="00:00:0.5"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>

button的双击事件发生时,执行什么操作,作用和Setter一样,只是写法不同

一些其他的疑惑和注释:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ControlTemplate TargetType="Button"  x:Key="MyButtonControltemplate">
        <!--控件模板内部的新布局-->
            <Border Name="border" BorderBrush="Red" BorderThickness="1">
            <StackPanel>
                <TextBlock x:Name="textblock" Foreground="Red" Text="{TemplateBinding Content}" HorizontalAlignment="Center"/>
                <Image Source="xyy.jpg"/>
            </StackPanel>
        </Border>
        <!--控件模板的Triggers-->
        <ControlTemplate.Triggers>
            <!--为什么trigger不用写Targetname,而setter要写呢?-->
            <!--Trigger是由引用了该控件目标的对象触发的,是有具体对象的-->
            <!--setter是去操作其他的对象做出相应的变化,要操作哪个对象呢?是不确定的,是开发者的逻辑,所以需要手动指定TargetName-->
            <Trigger Property="IsMouseOver" Value="true">
                <Setter Property="Border.BorderBrush" Value="Green" TargetName="border"/>
                <Setter Property="TextBlock.Text" Value="height=66" TargetName="textblock"/>
                <!--一个trigger可以添加多个setter-->
               <!--<Setter Property="TextBlock.Foreground" Value="Green" TargetName="textblock"/>-->
            </Trigger>
            <Trigger Property="Content" Value="123">
                <Setter Property="TextBlock.Text" Value="123+1" TargetName="textblock"/>
            </Trigger>
            <Trigger Property="Height" Value="1510">
                <Setter Property="TextBlock.Text" Value="Button的height是150" TargetName="textblock"/>
            </Trigger>
            <EventTrigger RoutedEvent="Button.MouseDoubleClick">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard >
                            <ColorAnimation Storyboard.TargetName="textblock" 
                                            Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                           To="Blue" Duration="00:00:0.5"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</ResourceDictionary>
View Code
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值