上次写了关于Trigger和Action的文章(Silverlight中的Action和Trigger),这次写一个Behavior的。Behavior的目的在于封装部分UI功能,那样就可以直接应用于元素而不用写任何代码。Behavior是一组相关操作的组合,它包含了Trigger和Action的工作。简单的说就是Trigger和Action的合体。
听说过Behavior的人一说到Behavior很容易想到拖动效果,这里我就做一个简单的在Canvas里的拖动行为。创建自定义Behavior需要从Behavior<DependencyObject>继承,并覆盖OnAttached和OnDetaching方法(和Trigger差不多)。还是用代码说话方便。
新建一个Behavior如下:
class Behavior1 : Behavior<Shape>
2: {
private Canvas _canvas;
bool _isDraging;
private Point _originalMousePosition;
6:
public Behavior1()
8: {
false;
10: }
11:
void OnAttached()
13: {
base.OnAttached();
new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
new MouseEventHandler(AssociatedObject_MouseMove);
new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
18: }
19:
void OnDetaching()
21: {
base.OnDetaching();
new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
new MouseEventHandler(AssociatedObject_MouseMove);
new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
26: }
27:
object sender, MouseButtonEventArgs e)
29: {
this.AssociatedObject);
31: _originalMousePosition = e.GetPosition(_canvas);
true;
this.AssociatedObject.CaptureMouse();
34: }
35:
object sender, MouseEventArgs e)
37: {
if (_isDraging)
39: {
//get the current mouse position
41: Point currentMousePosition = e.GetPosition(_canvas);
//calculate the current position of the shape
this.AssociatedObject.GetValue(Canvas.LeftProperty)) + (currentMousePosition.X - _originalMousePosition.X));
this.AssociatedObject.GetValue(Canvas.TopProperty)) + (currentMousePosition.Y - _originalMousePosition.Y));
//update original mouse position
46: _originalMousePosition = currentMousePosition;
47: }
48: }
49:
object sender, MouseButtonEventArgs e)
51: {
false;
this.AssociatedObject.ReleaseMouseCapture();
54: }
55: }
OnAttached里面注册MouseLeftButtonDown,MouseMove,MouseLeftButtonUp三个事件,OnDetaching里面取消注册。MouseLeftButtonDown事件获取Canvas和原始坐标,并设置开始拖动的标志;MouseMove事件不停的计算当前坐标与原始坐标的差值,并更新到Shape的坐标,从而实现移动(坐标的计算方法这里不多说);MouseLeftButtonUp结束拖动。这三个事件处理方法实际上可以看成三个Action,而Behavior本身可以看成一个Trigger。
下面该使用这个Behavior了。
因为是在Canvas上的拖动,所以要有一个Canvas,然后在上面放一个矩形和一个椭圆:
>
>
>
/>
>
>
>
>
/>
>
>
>
给它们分别应用上同一个Behavior,然后运行。结果很明显,两个Shape都能拖动了。
Behavior是个好东西,好处就不用说了,显而易见。其实在Blend(做Silverlight界面的)中已经预定义了不少Behaviors,在Microsoft Expression Gallery也可以获得他人的或共享自己的Behavior。
附上上面的源代码
参考资料:
http://hi.baidu.com/biongiser/item/6c3509355f9b49f32784f40b
http://kb.cnblogs.com/a/2253240/