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>