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>