Behavior,Trigger,TriggerAction深度解析

来源:互联网 发布:c语言中 什么意思 编辑:程序博客网 时间:2024/05/18 21:07
使用命令绑定是实现mvvm的重要途径,而Behavior,Trigger更是大大的简化这种方式,相信使用过 Behavior,Trigger的朋友深有体会,而 Trigger得灵活性之强又大大节省了很多的工作量,并且加速了编程效率。那么Behavior,Trigger,TriggerAction是如何实现的,使用过程中又要注意些什么?看我下面的分析。
  Behavior,Trigger,TriggerAction都继承于IAttachedObject接口和DependencyObject,下面是IAttachedObject的源码:

[代码]c#/cpp/oc代码:

    public interface IAttachedObject    {        void Attach(DependencyObject dependencyObject);        void Detach();        DependencyObject AssociatedObject { get; }    }
  AssociatedObject是被关联的对象,注意这是DependencyObject类型的,不是所有的对象都可以被关联。Behavior,Trigger,TriggerAction中都会保留有这个对象。
  Attach在被关联时会被调用,dependencyObject是被关联的对象。
  Detach在被解除关联是调用。
  
  在被关联是看看Behavior,Trigger,TriggerAction中内部实现的不同:

[代码]c#/cpp/oc代码:

public void Attach(DependencyObject dependencyObject)        {            if (dependencyObject != this.AssociatedObject)            {                if (this.AssociatedObject != null)                {                    throw new InvalidOperationException(...);                }                if ((dependencyObject != null) && !this.AssociatedObjectTypeConstraint.IsAssignableFrom(dependencyObject.GetType()))                {                    throw new InvalidOperationException(...);                }                this.associatedObject = dependencyObject;                this.OnAttached();            }        }
   以上是TriggerAction的实现。Trigger实现如下:

[代码]c#/cpp/oc代码:

        public void Attach(DependencyObject dependencyObject)        {            if (dependencyObject != this.AssociatedObject)            {                if (this.AssociatedObject != null)                {                    throw new InvalidOperationException(...);                }                if ((dependencyObject != null) && !this.AssociatedObjectTypeConstraint.IsAssignableFrom(dependencyObject.GetType()))                {                    throw new InvalidOperationException(...);                }                this.associatedObject = dependencyObject;                this.Actions.Attach(dependencyObject);                this.OnAttached();            }        }
   相比TriggerAction多了一行 this.Actions.Attach(dependencyObject)。Actions是TriggerAction的集合,在Trigger被关联的同时会一次关联集合众的TriggerAction。
  Behavior实现如下:

[代码]c#/cpp/oc代码:

public void Attach(DependencyObject dependencyObject)        {            if (dependencyObject != this.AssociatedObject)            {                if (this.AssociatedObject != null)                {                    throw new InvalidOperationException(...);                }                if ((dependencyObject != null) && !this.AssociatedType.IsAssignableFrom(dependencyObject.GetType()))                {                    throw new InvalidOperationException(...);                }                this.associatedObject = dependencyObject;                this.OnAssociatedObjectChanged();                this.OnAttached();            }        }
   Behavior多了一行AssociatedObjectChanged通知外界关联对象发生了改变。由上面的代码可以看出,3着实现大体相同,对象一但被附加,在被解除关联之前不可以被改变,并且被附加的类型与指定的类型相一致。
  Behavior,Trigger,TriggerAction这三者的区别与关联
   Trigger与TriggerAction是从属的关系,  Trigger 中保留有 TriggerAction 的集合,当 Trigger  被触发时,就会依次调用集合中的TriggerAction中的Invoke函数分别处理。 TriggerAction 中的Invoke是一个纯虚函数,这个函数中实现需要实现自己的逻辑代码。从TriggerBase继承的类可以调用InvokeActions来触发TriggerAction 的执行,以下是InvokeActions的实现:

[代码]c#/cpp/oc代码:

 protected void InvokeActions(object parameter)        {            if (this.PreviewInvoke != null)            {                PreviewInvokeEventArgs e = new PreviewInvokeEventArgs();                this.PreviewInvoke(this, e);                if (e.Cancelling)                {                    return;                }            }            foreach (System.Windows.Interactivity.TriggerAction action in this.Actions)            {                action.CallInvoke(parameter);            }        }
  当Trigger被触发时,会调用PreviewInvoke事件通知外界已被触发。这是一条广播链,当外界设置e.Cancelling=true时,Actions中所有 TriggerAction 都不会执行。wp中所有广播链都是采用的这种模式,当设置 e.Cancelling=true是广播并不会停止,但是会组织后续逻辑的执行。
  Behavior则没有特别的实现,在被关联时刻对被关联对象做任意的处理, Trigger 也一样。 Behavior 与 Trigger  的区别在于Trigger   可以通知到外界做额外的处理。所以 Behavior 与 Trigger 的功能是有重叠的,个人认为 Trigger  完全可以在Behavior  的基础上实现,由于Trigger  中Actions的存在,所以 Trigger   的灵活性和扩展性强于 Behavior  。
   Behavior,Trigger,TriggerAction如何使用我就不额外说明了,不会用的就多搜索,网上的示例很多。
   额外补充:System.Windows.Interactivity中仅有EventTrigger这一种 Trigger ,但是windows phone中提供了额外扩展的Behavior,Trigger和TriggerAction,在Microsoft.Phone.Interop.dll中,从引用中添加即可。
  使用注意事项: Behavior,Trigger,TriggerAction 经常在xmal中使用,并且都附加到了控件上,但是需要注意的是这3着不在可视化树种,所以绑定的时候无法直接使用ElementName这个属性。我有一种解决方案可以解决这个问题,在以后的博客中说明。
   要想最大化发挥Behavior,Trigger,TriggerAction的功效,仅仅使用官方提供的是不够,而自己定制才能将这三着的功能最大化发挥。如何订制就看我以后的博客吧。
  说一下win8中的Behavior,Trigger,TriggerAction,win8官方并没有这样的功能,要使用需要额外下载第三方库,在NuGet管理中搜索Interactivity即可获得,不过库的名称为Windows.Ui.Interactivity.

原创粉丝点击