WPF学习—模板

 

摘抄自《深入浅出WPF》第十一章

WPF中Template分为两大类:

1.ControlTemplate是算法内容的表现形式,控制控件的内部结构。决定控件“长成什么样子”,并让程序员有机会在控件原有的内部逻辑基础上扩展自己的逻辑

2.DataTemplate是数据内容的表现形式,决定数据显示,是简单的文本还是直观的图形动画

Template是“外衣”,ControlTemplate是控件外衣,DataTemplate是数据的外衣。

 

DataTemplate常用地方:

1、ContentControl的ContentTemplate属性,相当于给ContentControl的内容穿衣服

2、ItemsControl的ItemTeplate属性,相当于给ItemsControl的数据条目穿衣服

3、GridViewColumn的cellTemplate属性,相当于给GridViewColumn单元格数据穿衣服

 

实例:

XAML代码

<Window x:Class="LogoTemplateTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:LogoTemplateTest"
        mc:Ignorable="d"
        Title="DataTemplate" Height="400" Width="621.809">
    <Window.Resources>
        <local:AutomakerToLogoPathConverter x:Key="a2l"/>
        <local:NameToPhotoPathConverter x:Key="n2p"/>
        <DataTemplate x:Key="carDetailViewTemplate">
            <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" >
                <StackPanel Margin="5">
                    <Image  Width="400" Height="250" Source="{Binding Name,Converter={StaticResource n2p}}"/>
                    <StackPanel Orientation="Horizontal" Margin="5" >
                        <TextBlock Text="Name:" FontWeight="Bold" FontSize="20"/>
                        <TextBlock Text="{Binding Name}" FontSize="20" Margin="5,0"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Margin="5,0">
                        <TextBlock Text="Automaker:" FontWeight="Bold"/>
                        <TextBlock Text="{Binding Automaker}" Margin="5,0"/>
                        <TextBlock Text="Year:" FontWeight="Bold"/>
                        <TextBlock Text="{Binding Year}" Margin="5,0"/>
                        <TextBlock Text="Top Speed:" FontWeight="Bold"/>
                        <TextBlock Text="{Binding TopSpeed}" Margin="5,0"/>
                    </StackPanel>
                </StackPanel>
            </Border>
        </DataTemplate>
        <DataTemplate x:Key="carListItemViewTemplate">
            <Grid Margin="2">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding Automaker, Converter={StaticResource a2l}}"  Grid.RowSpan="3" Width="64" Height="64"/>
                    <StackPanel Margin="5,10">
                        <TextBlock Text="{Binding Name}" FontSize="16" FontWeight="Bold"/>
                        <TextBlock Text="{Binding Year}" FontSize="14"/>
                    </StackPanel>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <StackPanel Orientation="Horizontal" Margin="5">
        <UserControl ContentTemplate="{StaticResource carDetailViewTemplate}" Content="{Binding SelectedItem,ElementName=listBoxCars}"/>
        <ListBox x:Name="listBoxCars" Width="180" Margin="5,0" ItemTemplate="{StaticResource carListItemViewTemplate}"/>
    </StackPanel>
</Window>

后台代码:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitialCarList();
        }

        private void InitialCarList()
        {
            List<Car> carList = new List<Car>()
            {
                new Car() {Automaker="风剑",Name="风剑",Year="1990",TopSpeed="340" },
                new Car() {Automaker="风剑",Name="灰烬使者",Year="2001",TopSpeed="340" },
                new Car() {Automaker="风剑",Name="破碎的回忆",Year="2003",TopSpeed="340" },
                new Car() {Automaker="风剑",Name="霜之哀伤",Year="2008",TopSpeed="340" }
            };
            this.listBoxCars.ItemsSource = carList;
        }

    }

    public class Car
    {
        public string Automaker { get; set; }
        public string Name { get; set; }
        public string Year { get; set; }
        public string TopSpeed { get; set; }
    }

    public class AutomakerToLogoPathConverter:IValueConverter
    {
        public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
        {
            string uriStr = string.Format(@"Resources\Logos\{0}.jpg", (string)value);
            return  new BitmapImage(new Uri(uriStr, UriKind.Relative));
        }

        public object ConvertBack(object value,Type targetType,object parameter,CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class NameToPhotoPathConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string uriStr = string.Format(@"Resources\Images\{0}.jpg", (string)value);
            return new BitmapImage(new Uri(uriStr, UriKind.Relative));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

ContentTemplate=“{StaticResource carDetailViewTemplate}”,相当于给普通UserControl的数据内容穿上一件外衣,以x:Key="carDetailViewTemplate"标记的DataTemplate资源

ItemTemplate=“{StaticResource carListItemViewTemplate}”,是把一件数据外衣交给ListBox。当ListBox.ItemsSource被赋值时,ListBox为子项换上外衣,以x:Key="carListItemViewTemplate"标记的DataTemplate资源

 

ControlTemplate主要用处:

1、通过更换ControlTemplate改变控件外观,使之具有更优的用户使用体验及外观

2、借助ControlTemplate,程序员可以与设计师并行工作,程序员可以先用WPF标准控件进行编程,等设计师的工作完成后,只需要把新的ControlTemplate应用到程序中

 

DataTemplate和ControlTemplate的关系:

控件作为数据和行为的载体,是个抽象的概念,控件内部结构(控制控件视觉表现,即长成什么样子),数据显示结构(数据长成什么样子)都是靠Template生成的。决定控件外观的是ControlTemplate,决定数据外观的是DataTemplate,它们是Control 类的Template和ContentTemplate两个属性的值。作用范围如图:

 

DataTemplate和ControlTemplate的应用:

为Template设置其应用目标有两种方法,一种是逐个设置控件的Template/ContentTemplate/ItemsTemplate/CellTemplate等属性,不想应用Template的控件不设置;另一种是整体应用,即把Template应用在某个类型的控件或数据上

把ControlTemplate应用在所有目标上需要借助Style来实现,但是Style不能标记x:Key

实例:

XAML代码

<Window x:Class="ParaseControlTest.TextBoxStyle"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ParaseControlTest"
        mc:Ignorable="d"
        Title="TextBoxStyle" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type TextBox}" >
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="Bd" CornerRadius="5" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"   SnapsToDevicePixels="true">
                            <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="Height" Value="25"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBox/>
        <TextBox/>
        <TextBox Style="{x:Null}" Margin="5"/>
    </StackPanel>
</Window>

 

把DataTemplate应用在某个数据类型上的方法是设置DataTemplate的DataType属性,并且DataTemplate作为资源也不能带有x:Key标记

实例

XAML代码

<Window x:Class="DataTypeTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
        xmlns:local="clr-namespace:DataTypeTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="Unit">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <Grid>
                        <Rectangle Stroke="Yellow" Fill="Orange" Width="{Binding XPath=@Price}"/>
                        <TextBlock Text="{Binding XPath=@Year}"/>
                    </Grid>
                    <TextBlock Text="{Binding XPath=@Price}" Margin="5,0"/>
                </StackPanel>
            </Grid>
            
        </DataTemplate>
        <XmlDataProvider x:Key="ds" XPath="Units/Unit">
            <x:XData>
                <Units xmlns="">
                    <Unit Year="2001 年" Price="100"/>
                    <Unit Year="2002 年" Price="120"/>
                    <Unit Year="2003 年" Price="140"/>
                    <Unit Year="2004 年" Price="160"/>
                    <Unit Year="2005 年" Price="180"/>
                    <Unit Year="2006 年" Price="200"/>
                </Units>
            </x:XData>
        </XmlDataProvider>
        
    </Window.Resources>
    <StackPanel>
        <ListBox ItemsSource="{Binding Source={StaticResource ds}}"/>
        <ComboBox ItemsSource="{Binding Source={StaticResource ds}}" Margin="5"/>
    </StackPanel>
</Window>

 

 

XAML可以方便地表示带有层级的数据。同时WPF准备了TreeView和MenuItem控件来显示层级数据。能够帮助层级控件显示层级数据的模板是HierarchicalDataTemplate。

实例

添加Data.xml文件,代码如下

<?xml version="1.0" encoding="utf-8" ?> 
<Data xmlns="">
  <Grade Name="一年级">
    <Class Name="甲班">
        <Group Name="A组"/>
        <Group Name="B组"/>
        <Group Name="C组"/>
     </Class>
    <Class Name="乙班">
      <Group Name="A组"/>
      <Group Name="B组"/>
      <Group Name="C组"/>
    </Class>
  </Grade>
  <Grade Name="二年级">
    <Class Name="甲班">
      <Group Name="A组"/>
      <Group Name="B组"/>
      <Group Name="C组"/>
    </Class>
    <Class Name="乙班">
      <Group Name="A组"/>
      <Group Name="B组"/>
      <Group Name="C组"/>
    </Class>
  </Grade>
  <Operation Name="文件" Gesture="F">
    <Operation Name="新建" Gesture="N">
      <Operation Name="项目" Gesture="Control+P"/>
      <Operation Name="网站" Gesture="Control+W"/>
      <Operation Name="文档" Gesture="Control+D"/>
    </Operation>
    <Operation Name="保存" Gesture="Control+S"/>
    <Operation Name="打印" Gesture="Control+P"/>
    <Operation Name="退出" Gesture="Control+X"/>
  </Operation>
  <Operation Name="编辑" Gesture="F">
      <Operation Name="拷贝" Gesture="Control+C"/>
      <Operation Name="剪切" Gesture="Control+X"/>
      <Operation Name="粘贴" Gesture="Control+V"/>
  </Operation>
</Data>

主窗口XAML代码:

<Window x:Class="XmlDataProviderTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:XmlDataProviderTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <XmlDataProvider x:Key="ds" Source="Data.xml" XPath="Data/Grade"/>
        <HierarchicalDataTemplate DataType="Grade" ItemsSource="{Binding XPath=Class}">
            <TextBlock Text="{Binding XPath=@Name}"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="Class" ItemsSource="{Binding XPath=Group}">
            <RadioButton Content="{Binding XPath=@Name}" GroupName="gn"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding XPath=Student}">
            <CheckBox Content="{Binding XPath=@Name}"/>
        </HierarchicalDataTemplate>
        <XmlDataProvider x:Key="opera" Source="Data.xml" XPath="Data/Operation">
        </XmlDataProvider>
        <HierarchicalDataTemplate DataType="Operation" ItemsSource="{Binding XPath=Operation}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding XPath=@Name}" Margin="10,0"/>
                <TextBlock Text="{Binding XPath=@Gesture}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <StackPanel MenuItem.Click="StackPanel_Click" >
        <TreeView Margin="5" ItemsSource="{Binding Source={StaticResource ds}}"/>
        <Menu ItemsSource="{Binding Source={StaticResource opera}}"  />
    </StackPanel>
</Window>

事件处理:

private void StackPanel_Click(object sender, RoutedEventArgs e)
        {
            MenuItem mi = e.OriginalSource as MenuItem;
            XmlElement xe = mi.Header as XmlElement;
            MessageBox.Show(xe.Attributes["Name"].Value);
        }

 

 

寻找控件:由ControlTemplate或DataTemplate生成的控件都是“由Template生成的控件”ControlTemplate和DataTemplate两个类均派生自FrameworkTemplate类,这个类有个名为FindName的方法供检索内部控件。

寻找由ControlTemplate生成的控件:

XAML代码如下

<Window x:Class="FindTempControlTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FindTempControlTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="cTmp">
            <StackPanel Background="Orange">
                <TextBox x:Name="textBox1" Margin="6"/>
                <TextBox x:Name="textBox2" Margin="6,0"/>
                <TextBox x:Name="textBox3" Margin="6"/>
            </StackPanel>
        </ControlTemplate>
    </Window.Resources>
    <StackPanel Background="Yellow">
        <UserControl x:Name="uc" Template="{StaticResource cTmp}" Margin="5"/>
        <Button Content="Find By Name" Width="120" Height="30" Click="Button_Click"/>
    </StackPanel>
</Window>

后台代码:

public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TextBox tb = this.uc.Template.FindName("textBox1",this.uc) as TextBox;
            tb.Text = "Hello World";
            StackPanel sp = tb.Parent as StackPanel;
            (sp.Children[1] as TextBox).Text = "hello ControlTemplate";
            (sp.Children[2] as TextBox).Text = "I can find you";
        }

 

寻找有DataTemplate生成的控件

后台代码:

public partial class ComplexTest : Window
    {
        public ComplexTest()
        {
            InitializeComponent();
        }

        private void textBoxName_GotFocus(object sender, RoutedEventArgs e)
        {
            TextBox tb = e.OriginalSource as TextBox;
            ContentPresenter cp = tb.TemplatedParent as ContentPresenter;
            Student stu = cp.Content as Student;
            this.listViewStudent.SelectedItem = stu;

            ListViewItem lvi = this.listViewStudent.ItemContainerGenerator.ContainerFromItem(stu) as ListViewItem;
            CheckBox chb = this.FindVisualChild<CheckBox>(lvi);
            MessageBox.Show(chb.Name);
        }

        private ChildType FindVisualChild<ChildType>(DependencyObject obj) where ChildType:DependencyObject
        {
            for(int i=0;i<VisualTreeHelper.GetChildrenCount(obj);i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if(child!=null&&child is ChildType)
                {
                    return child as ChildType;
                        }
                else
                {
                    ChildType childOfChild = FindVisualChild<ChildType>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
    }

public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Skill { get; set; }
public bool HasJob { get; set; }
}

 

XAML代码:

<Window x:Class="FindDataTemplateTest.ComplexTest"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
        xmlns:local="clr-namespace:FindDataTemplateTest"
        mc:Ignorable="d"
        Title="ComplexTest" Height="300" Width="300">
    <Window.Resources>
        <c:ArrayList x:Key="stuList">
            <local:Student Id="1" Name="Timoty Liu" Skill="WPF" HasJob="True"/>
            <local:Student Id="2" Name="Tom Chang" Skill="BI/SQL" HasJob="True"/>
            <local:Student Id="3" Name="Guang Chong" Skill="Writing" HasJob="False"/>
            <local:Student Id="4" Name="Shanshan" Skill="C#/Java" HasJob="False"/>
            <local:Student Id="5" Name="Pingping Zhang" Skill="Writing" HasJob="False"/>
            <local:Student Id="6" Name="Kenny Tian" Skill=".NET" HasJob="False"/>
        </c:ArrayList>
        <DataTemplate x:Key="nameDT">
            <TextBox x:Name="textBoxName" Text="{Binding Name}" GotFocus="textBoxName_GotFocus"/>
            
        </DataTemplate>
        <DataTemplate x:Key="skillDT">
            <TextBox x:Name="textBoxSkill" Text="{Binding Skill}"/>
        </DataTemplate>
        <DataTemplate x:Key="hjDT">
            <CheckBox x:Name="checkBoxJob" IsChecked="{Binding HasJob}"/>
        </DataTemplate>
    </Window.Resources>
    <Grid Margin="5">
        <ListView x:Name="listViewStudent" ItemsSource="{StaticResource stuList}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}"/>
                    <GridViewColumn Header="姓名" CellTemplate="{StaticResource nameDT}"/>
                    <GridViewColumn Header="技术" CellTemplate="{StaticResource skillDT}"/>
                    <GridViewColumn Header="已工作" CellTemplate="{StaticResource hjDT}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

 

Trigger,触发器,即当某些条件满足时会触发一个行为。触发器比较像事件。事件一般由用户操作触发,而触发器除了有事件触发器型的EventTrigger外还有数据变化触发型的Trigger/DataTrigger以及多条件触发的MultiTrigger/MultiDataTrigger等。

 

Trigger和MultiTrigger实例:

Xaml代码:

<Window x:Class="CheckBoxTriggerTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CheckBoxTriggerTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <!--Trigger Property="IsChecked" Value="true">
                    <Trigger.Setters>
                        <Setter Property="FontSize" Value="20"/>
                        <Setter Property="Foreground" Value="Orange"/>

                    </Trigger.Setters>
                </Trigger-->
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsChecked" Value="true"/>
                        <Condition Property="Content" Value="正如我悄悄的来"/>
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="FontSize" Value="20"/>
                        <Setter Property="Foreground" Value="Orange"/>
                    </MultiTrigger.Setters>
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <CheckBox Content="悄悄的我走了" Margin="5"/>
        <CheckBox Content="正如我悄悄的来" Margin="5"/>
        <CheckBox Content="挥一挥衣袖" Margin="5"/>
        <CheckBox Content="不带走一片云彩" Margin="5"/>
    </StackPanel>
</Window>

 

DataTrigger实例

Xaml代码:

<Window x:Class="DataTriggerTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataTriggerTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:L2BConverter x:Key="cvtr"/>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self},Path=Text.Length,Converter={StaticResource cvtr}}" Value="false">
                    <Setter Property="BorderBrush" Value="Red"/>
                    <Setter Property="BorderThickness" Value="1"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBox Margin="5"/>
        <TextBox Margin="5"/>
        <TextBox Margin="5"/>
    </StackPanel>
</Window>

后台代码:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class L2BConverter:IValueConverter
    {
        public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
        {
            int textLength = (int)value;
            return textLength > 6 ? true : false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

 

MultiDataTrigger实例

Xaml代码

<Window x:Class="DataTriggerTest.MultiTrigger"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataTriggerTest"
        mc:Ignorable="d"
        Title="MultiTrigger" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding ID}" Width="60"/>
                            <TextBlock Text="{Binding Name}" Width="120"/>
                            <TextBlock Text="{Binding Age}" Width="60"/>
                        </StackPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=ID}" Value="2"/>
                        <Condition Binding="{Binding Path=Name}" Value="Tom"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Property="Background" Value="Orange"/>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <ListBox x:Name="listBoxStudent" Margin="5"/>
    </StackPanel>
</Window>

后台代码:

public partial class MultiTrigger : Window
    {
        public MultiTrigger()
        {
            InitializeComponent();
            InitialStuList();
        }

        private void InitialStuList()
        {
            List<Student> stuList = new List<Student>()
            {
                new Student() {ID=1,Name="Tim",Age=10 },
                new Student() {ID=2,Name="Tom",Age=11 }
            };
            this.listBoxStudent.ItemsSource = stuList;
        }
    }

    public class Student
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

 

事件触发EventTrigger

EventTrigger是触发器中特殊的一个,首先,它不是由属性值或数据的变化来触发而是由事件来触发;其次,被触发后并非应用一组Setter,而是执行一段动画。因此,UI层的动画效果往往与EventTrigger相关联

实例:

XAML代码

<Window x:Class="EventTriggerTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:EventTriggerTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="Button">
            <Style.Triggers>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
                            <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
                            <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <Button Width="40" Height="40" Content="OK"/>
    </StackPanel>
</Window>

 

posted @ 2018-10-17 21:57  梦九龍  阅读(450)  评论(0编辑  收藏  举报