上次写了关于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/

 

相关文章: