学WPF 的一定知道,触发器是非常强大。这是一种对象,该对象侦听特定条件(例如事件触发或属性设置为某个值),并调用一项或多项关联的操作作为响应。行为就是一组对象,在没有来自触发器或类似触发器的项目的外部通知的情况下也可以执行用户定义的动作。尽管需要满足某种条件,但它不必由触发器调用。
一、了解Behavior
1 .Blend中包含三种基本的行为:a) Behavior --将状态信息和零个或更多个 ICommand 封装到一个可附加的对象中,提供对象绑定和撤销绑定的事件,适应大多数情况。
b) TriggerAction --代表封装功能单元的可附加对象。
c) TargetTriggerAction --代表一项操作,可以将该操作确定为目标以影响不同于其 AssociatedObject 的对象,提供了更高层次的抽象设计,AssociatedObject 就 是被绑定的上层对象。
2.使用行为的泛型,如 Behavior<T>,TriggerAction<T>,TargetTriggerAction<T>
因为这是基础结构类。操作设计者应从 泛型 而不是从此类中派生 。可以看下面的结构图
<>
二、在Blend 3.0中应用Behavior
- 新建项目
- 拖动一个圆形控件到白板
找到Behavior组件,这里我们选择MouseDragElementBehavior(可拖动行为)。
将其拖动到白板上的圆形控件上,或者是Objects And Timeline 面板上的Ellipse对象上,我们得到如下图。
Ok,我们为圆形添加了一个可拖动的行为,即现在圆形在运行后就可以自由拖动了,可以运行下看看.
很简洁,很方便,很强大,Allways , No Code。 - 再进一步,我们为原型添加MouseEnter的VisualState,其实就是鼠标移入的一种样式改变。
注意按右边加号添加VisualState,并改名。
当此VisualState前有个红色圆点,表示现在已经开始记录状态,你可以修改Ellipse控件的外观了,结束了按下上面的Base退出编辑。
选择GoToStateAction 行为,并将其拖到Ellcipse上面。
选中GoToStateAction,将属性面板中StateName选择为InCircle状态,EventName设置为MouseEnter。
Ok,我们已经为圆添加了鼠标移入事件。运行看看吧。 - 当然,鼠标移入之后就一直保持那个状态了,那就再给它加个OutCircle的虚拟状态,自己尝试吧,但现在不要急着将再创建个Behavior,我们留给下面的TiggerAction来完成,以便区别两者的不同。
三、在Blend 3 中应用TiggerAction
- 在上面项目基础上我们新建项,File –>New Item,取名为OutStateAction.cs
按下Shift+Ctrl+B给整个项目编译一下。这是我们再到Assets面板的Behavior中就会发现我们刚才创建的动作,将它拖到我们的圆上。
修改行为组件的属性,这里我们要让对象MouseLeave事件触发时执行指定的动作,然而这个动作在哪实现呢?? - 打开OutStateAction.cs,我们发现里面有注释提示你,Invoke函数就是你想要实现的动作,Ok,加入你的代码吧。
这里我们想让圆的颜色变为蓝色,那么如何获取这个被附加的上层对象呢,前面已经介绍过,TriggerAction中的AssociatedObject 属性就是被绑定的上层对象的引用。有了这个引用,我们可以做很多事情了,在Invoke函数中插入下面的代码
var ellipse = this.AssociatedObject as Ellipse;
ellipse.Fill = new SolidColorBrush(Colors.Red); - 好了,现在可以运行下看下效果(这里在程序中改变Fill的颜色后再使用VisualState好像就失效了,估计应该是覆盖了吧,有大侠指点下:-)
三、Blend 3 中应用TargetTriggerAction
默认情况下,尽管你可以更改操作所影响的对象,但操作只能访问它所附加到的元素(父元素),即 AssociatedObject 属性。为了消除这种上下级的依赖,实现松散耦合的操作,由用户自定义操作的目标,我们就从 TargetedTriggerAction(而不是 TriggerAction)中扩展表示操作的类。
- 在上面基础上,我们新建一个类。并让它继承自TargetedTriggerAction<DependencyObject>
- TargetedTriggerAction<DependencyObject> 依然有一个Invoke函数需要你重写,但是这次你要针对的对象是由程序在运行时提供,该类本身并不了解具体的Target Object是什么,触发器是什么。但它提供了一个访问这个抽象Target的引用。
我们先在InVoke中添加如下简单的事件
protected override void Invoke(object o)
{
MessageBox.Show("Hello world");
}
不管外界是何触发器,一旦满足了触发条件,程序就会执行Invoke,并将获取当前Target的引用 - Shift + Ctrl +B 编译后,可以看到我们的ObjectTriggerAction行为组件,把它拖到圆上
看到TargetName已经设为ellipse了,当然,我们可以改成其他对象为目标
修改EventName 为MouseLeftButtonUp,当鼠标按下松开后,我们的程序就会自动将Target对象输送给Action了,设计得很完美。 - 运行一下看到是否拖动完后会弹出个对话框呢,那就OK了。
其实Behavior的功能远比我谈到的这些要强大,只是这里结合Blend 3的基本操作界面而谈,所以不讨论那些理论性的东西,想深入研究的请关注Blend 3 SDK 官方手册。
还有一点要注意,Behavior的所有功能组件都在System.windows.Interactivity.DLL中,而这个只是Blend 3 SDK 中自带的,并不包含在Silverlight 3.0 中,只因为我们的项目是用Blend开发的,所以IDE会自动添加引用,如果用Visual Studio 中开发还需要手动导入.
真的很佩服Blend 3 的设计者创造了这么强大的IDE, 其实往往我们评论一些软件工具的时候,我们了解的只是冰山一角。
作者 :双宇
本文系原创文章,转载请注明出处,谢谢!