1. 程式人生 > >WPF學習—模板

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 [email protected]}"/>
                        <TextBlock Text="{Binding [email protected]}"/>
                    </Grid>
                    <TextBlock Text="{Binding [email protected]}" 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 [email protected]}"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="Class" ItemsSource="{Binding XPath=Group}">
            <RadioButton Content="{Binding XPa[email protected]}" GroupName="gn"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding XPath=Student}">
            <CheckBox Content="{Binding [email protected]}"/>
        </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 [email protected]}" Margin="10,0"/>
                <TextBlock Text="{Binding [email protected]}"/>
            </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>