• 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>

    运行结果如图:

    image

    很显然,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>

    运行如果如下:

    image

    这里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>

    运行结果如下:

    image

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

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

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

  • 相关阅读:
    Linux sed命令实例详解
    hadoop2.0 和1.0的区别
    linux如何修改主机名
    hadoop主节点(NameNode)备份策略以及恢复方法
    Hadoop 添加删除数据节点(datanode)
    Hadoop常见错误及处理方法
    【转】ImageView.ScaleType属性
    MonoBehaviour.print和Debug.Log是同样的作用
    unity自带寻路Navmesh入门教程
    前向渲染路径细节 Forward Rendering Path Details
  • 原文地址:https://www.cnblogs.com/xiaogui9527/p/3034944.html
Copyright © 2020-2023  润新知