• 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
  • 相关阅读:
    Extjs的学习及MIS系统实践应用(系列文章)
    Extjs的js函数
    【VS Code】使用技巧
    【算法技巧】算法技巧记录
    【踩坑记录】vs2017 git 版本控制问题
    【IDE】解决国内下载安装vs 过慢问题
    【c#基础】.Net编译器平台
    【查看IIS站点日志】
    【项目管理】人月神话
    【c#基础】反射、元数据和动态编程
  • 原文地址:https://www.cnblogs.com/1024E/p/15744314.html
Copyright © 2020-2023  润新知