【WPF】Silverlight中的Action与Trigger

最近做的Silverlight项目上用到了大量的拖拽,自动跟随等功能,由于赶时间,加上对Silverlight半生不熟,用的是最简单也是最不好维护的方法。项目忙完了闲下来,想重构一下代码,想起了Trigger和Action这两个东西,当初接触这两个东西不深,只是认识,不知道用。现在正好可以好好学习一下,参考了重多大神的代码之后,终于初步熟悉了它们。这里分享一下我对Trigger和Action的认识。

我用一个最简单的例子来说明Action与Trigger,点击一个Button弹出MessageBox。

建立一个Silverlight Application,引用System.Windows.Interactivity.dll程序集(这个程序集很重要,是使用Trigger,Action,Behavior必须引用的)。我们在MainPage里放一个Button并给一个Click事件。

xaml代码如下:

   1: <UserControl x:Class="SilverlightApplication1.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     mc:Ignorable="d"
   7:     d:DesignHeight="300" d:DesignWidth="400">
   8:  
   9:     <Grid x:Name="LayoutRoot" Background="White">
  10:         <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top" Click="button1_Click" />
  11:     </Grid>
  12: </UserControl>

cs代码如下:

   1: public partial class MainPage : UserControl
   2: {
   3:     public MainPage()
   4:     {
   5:         InitializeComponent();
   6:     }
   7:  
   8:     private void button1_Click(object sender, RoutedEventArgs e)
   9:     {
  10:         MessageBox.Show("Hello World!");
  11:     }
  12: }

很简单,这是最传统的做法。

下面Action要上场了。所谓Action,就是去执行某些操作。可以根据需要创建自己的Action,常见的需要创建Action的情况有:改变属性、调用方法、打开窗口、导航到某个页面、设置焦点等。自定义Action可从 TriggerAction<DependencyObject>TargetedTriggerAction<DependencyObject>继承,区别在于操作对象是关联对象还是特定的目标对象,实现时覆盖Invoke方法即可。我们新建一个简单的Action,代码如下:

   1: public class Action1 : TriggerAction<DependencyObject>
   2: {
   3:     public Action1()
   4:     {
   5:         
   6:     }
   7:  
   8:     protected override void Invoke(object o)
   9:     {
  10:         MessageBox.Show("Hello World! This message comes from an action.");
  11:     }
  12: }

在Invoke方法里Show一个MessageBox。这样,一个Action这创建好了。如何使用它呢?看下面的代码。

xaml代码:

   1: <UserControl x:Class="SilverlightApplication1.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
   7:     xmlns:local="clr-namespace:SilverlightApplication1"
   8:     mc:Ignorable="d"
   9:     d:DesignHeight="300" d:DesignWidth="400">
  10:  
  11:     <Grid x:Name="LayoutRoot" Background="White">
  12:         <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top">
  13:             <i:Interaction.Triggers>
  14:                 <i:EventTrigger EventName="Click">
  15:                     <local:Action1 />
  16:                 </i:EventTrigger>
  17:             </i:Interaction.Triggers>
  18:         </Button>
  19:     </Grid>
  20: </UserControl>

运行结果如图:

很显然,Button的单击调用了那个Action,Button不再去触发xaml.cs里的那个事件处理方法了,而了触发了之前新建的Action1。回到xaml代码,EventTrigger是Silverlight自带的一个触发器(Trigger)。Trigger一量触发,就会执行对应的Action。这里我们把Action1与EventTrigger关联到一起(“关联”这个词可能用得不合适,反正就这个意思),EventTrigger触发Click事件,执行Action弹出MessageBox。而xaml.cs文件里的代码不再需要了。它的好处是不是已经看出来了?有效的分离了UI与后台代码。

下面Trigger正式登场。所谓Trigger,就是监听某些条件的变化,比如事件触发,属性值改变等,进而触发一些动作的发生。这些Triggers可能是EventTrigger、CollisionTrigger 等,当然更多的或许是创建自己的Trigger。自定义Trigger只需要从TriggerBase<DependencyObject>继承,并覆盖OnAttached和OnDetaching方法即可。我面来创建一个Trigger。代码如下:

   1: public class Trigger1 : TriggerBase<Button>
   2: {
   3:     protected override void OnAttached()
   4:     {
   5:         base.OnAttached();
   6:         this.AssociatedObject.Click += new RoutedEventHandler(Trigger1_Click);
   7:     }
   8:  
   9:     protected override void OnDetaching()
  10:     {
  11:         base.OnDetaching();
  12:         this.AssociatedObject.Click -= new RoutedEventHandler(Trigger1_Click);
  13:     }
  14:  
  15:     protected void Trigger1_Click(object sender, RoutedEventArgs e)
  16:     {
  17:         MessageBox.Show("Hello World! This message comes from a trigger.");
  18:     }
  19: }

代码中我们用到了AssociationObject这个属性,这个属性表示绑定Trigger的对象,这里是一个Button,OnAttached中注册一个Click事件处理方法,OnDetching中取消注册(如果不取消注册,当这个Button上其它触发器触发时,这个触发器的效果还会重现,因为Click触发之后委托链上所有注册方法都会执行, 具体情况具体分析是否需要取消注册)。

在Xaml中这样来使用这个Trigger:

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top">
   3:         <i:Interaction.Triggers>
   4:             <local:Trigger1 />
   5:         </i:Interaction.Triggers>
   6:     </Button>
   7: </Grid>

运行如果如下:

这里Trigger1被触发了。

其实,触发器(Trigger)和动作(Action)是协同工作的。当某事件发生的时候,Trigger就会触发并调用一个Action,Trigger和Action组成了最简单的行为(Behavior下次再讨论)表现形式。

最后,我们让Trigger1和Action1协同工作一下。Trigger1的代码改一改:

   1: public class Trigger1 : TriggerBase<Button>
   2: {
   3:     protected override void OnAttached()
   4:     {
   5:         base.OnAttached();
   6:         this.AssociatedObject.Click += new RoutedEventHandler(Trigger1_Click);
   7:     }
   8:  
   9:     protected override void OnDetaching()
  10:     {
  11:         base.OnDetaching();
  12:         this.AssociatedObject.Click -= new RoutedEventHandler(Trigger1_Click);
  13:     }
  14:  
  15:     protected void Trigger1_Click(object sender, RoutedEventArgs e)
  16:     {
  17:         InvokeActions(null);
  18:     }
  19: }

Trigger1_Click方法里调用InvokeActions来执行“关联”到这个Trigger上的Action。Xaml如下:

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top">
   3:         <i:Interaction.Triggers>
   4:             <local:Trigger1>
   5:                 <local:Action1 />
   6:             </local:Trigger1>
   7:         </i:Interaction.Triggers>
   8:     </Button>
   9: </Grid>

运行结果如下:

这里,Button绑定了Trigger1,Attach这个Trigger1时把Click事件注册上(OnAttached方法。关于Attach,请参考“附加属性”),所以单击Button就调用了绑定在Trigger1上的Action1。

至于这两个东西的好处就不必多说了,分离了UI与代码,提高了代码的复用。

好了,初学Trigger和Action,大致缕了一下它们之间的关系,就简单介绍到这,欢迎一起讨论。更神奇的Behavior将在下篇中介绍

附上上面的源代码

时间: 2024-11-10 14:03:32

【WPF】Silverlight中的Action与Trigger的相关文章

WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示

原文:WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示 为方便描述, 这里仅以正方形来做演示, 其他图形从略. 运行时效果图: XAML代码:// Transform.XAML <Canvas Width="700" Height="700" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://sc

[Win10]1 WPF和WP8 Silverlight中的导航问题

一.Frame.Page框架的相关介绍 1.Frame类: 继承层次结构 System.Object   System.Windows.Threading.DispatcherObject     System.Windows.DependencyObject       System.Windows.Media.Visual         System.Windows.UIElement           System.Windows.FrameworkElement           

WPF和WP8 Silverlight中的导航问题

一.Frame.Page框架的相关介绍 1.Frame类: 继承层次结构 System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.W

WPF基础到企业应用系列7——深入剖析依赖属性(WPF/Silverlight核心)

一. 摘要 首先圣殿骑士非常高兴这个系列能得到大家的关注和支持.这个系列从七月份開始到如今才第七篇,上一篇公布是在8月2日,掐指一算有二十多天没有继续更新了,最主要原因一来是想把它写好,二来是由于近期几个月在筹备"云计算之旅"系列,所以一再推迟了公布进度. 之前一直都没有想过要录制视频.基本的原因还是怕自己知识有限,从而误导他人,所曾经几次浪曦和51CTO邀请录制视频,我都以工作忙.公司内部培训须要时间和自己有待提高等理由委婉的拒绝了,说实在的.自己也知道自己还有非常多地方有待提高.还

Silverlight中使用MVVM(3)—进阶

这篇主要引申出Command结合MVVM模式在应用程序中的使用 我们要做出的效果是这样的 就是提供了一个简单的查询功能将结果绑定到DataGrid中,在前面的基础上,这个部分相对比较容易实现了 我们在PageViewModel中添加两个属性 private string _searchText; //查询关键字 public string SearchText { get { return _searchText; } set { _searchText = value; if (Propert

WPF/Silverlight HierarchicalDataTemplate 模版的使用(转)

上一篇 对Wpf/Silverlight Template 进行了总结,本篇继续上一篇,主要是介绍 HierarchicalDataTemplate 的使用方法.HierarchicalDataTemplate 继承于DataTemplate,被称之为"层级式数据模板",主要是应用层级比较明显数据集合,其典型的应用就是对TreeView控件进行数据绑定,接下来就在Silverlight 5 下进行一下演示.最近有个卖凉茶的节目比较火,叫中国好声音,里面的导师和其歌手的分组就是个层级结构

在 WPF 程序中使用 MVVM 模式

MVVM 模式是一个很久之前的技术了,最近因为一个项目的原因,需要使用 WPF 技术,所以,重新翻出来从前的一段程序,重温一下当年的技术. MVVM 模式 MVVM 实际上涉及三个部分,Model, View 和 ViewModel ,三者的关系如下图所示. 在三部分的关系中,视图显示的内容和操作完全依赖于 ViewModel. Model 是应用程序的核心,代表着最大.最重要的业务资产,因为它记录了所有复杂的业务实体.它们之间的关系以及它们的功能. Model 之上是 ViewModel.Vi

Silverlight中图片显示

silverlight中显示一个图片有很多的中方法,xaml中的image控件或者自定编写程序来生成image控件. silverlight中显示的图片只能是Bitmap, JPG, PNG(64位颜色的或者灰色的PNG不支持). 请注意那个gif这个动画图片是不能使用的. 下面就一一的说说显示图片的方法. (1) 我们拷贝一个图片到新建的silverlight程序集中,然后新建一个silverlight user control, 名为ImagePage.xaml.然后添加一个Image控件到

MvvmLight学习篇—— Mvvm Light Toolkit for wpf/silverlight系列(导航)

一.Mvvm Light Toolkit for wpf/silverlight系列之准备工作 二.Mvvm Light Toolkit for wpf/silverlight系列之搭建mvvmlight开发框架 三.Mvvm Light Toolkit for wpf/silverlight系列之数据绑定 四.Mvvm Light Toolkit for wpf/silverlight系列之Command和Events 五.Mvvm Light Toolkit for wpf/silverli