Behavior的实现原理以及在MVVM框架的妙用
摘要 : Behavior 是微软在Blend中新添加的功能,通过在Blend中通过拖拖鼠标很容易就可以通过behavior给元素添加移动 旋转 拉伸等等效果,并且实现行为的代码和UI元素是分离的因此行为是可以复用的大大的提高了编程的灵活性并减少了编写重复枯燥的代码。虽然行为是在Blend中使用的并且使用起来十分简答,但是背后的实现原理以及思想还是值得研究一番。本文将从behavior的基本概念、具体使用方法、实现原理以及在项目中的具体实践对behavior做一个介绍。
大纲:
1 Behavior基本概念
Behavior 行为是微软在Blend中提供的一种新的功能,我觉得其最大的好处我觉得是可以复用,可以将实现的一个功能比如一个动画效果 事件响应方法等附加到某个元素上 那么被附加的元素就具有了相应的功能而不需要重复实现这些功能。比如Blend中自带了一些已经实现的行为只需要拖到需要用到的元素上元素就具有了对应的行为 比如拖动、放大缩小等等; 实现行为的代码和使用行为的元素可以处于不同的程序集中两者是松耦合的。
2 Blend 中的Behavior以及自定义Behavior
在blend中有一些的行为如图1-1所示:
使用非常简单只需要将相应的行为拖到需要应用此行为的元素上即可
<i:Interaction.Behaviors>
<el:MouseDragElementBehavior/>
</i:Interaction.Behaviors>
以上代码是将行为拖到某个元素后Blend自动生成的代码,其实就是给元素赋了一个附加属性的值,被附加该行为的元素就可以拖动了。
自定义行为:
以上是Blend中以实现的行为,接下来介绍如何自定义行为这里也是自己实现一个支持鼠标拖动的行为。
using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Interactivity; namespace BehaviorLibrary { public class DiagInCanvasBehavior:Behavior<UIElement> { private Canvas canvas; private bool isDragging=false; private Point mousePoint; protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.MouseDown += AssociatedObject_MouseDown; this.AssociatedObject.MouseMove += AssociatedObject_MouseMove; this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp; } protected override void OnDetaching() { base.OnDetaching(); this.AssociatedObject.MouseDown -= AssociatedObject_MouseDown; this.AssociatedObject.MouseMove -= AssociatedObject_MouseMove; this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp; } private void AssociatedObject_MouseDown(object sender, MouseButtonEventArgs e) { if (canvas == null) { canvas = (Canvas)System.Windows.Media.VisualTreeHelper.GetParent(this.AssociatedObject); } isDragging = true; mousePoint = e.GetPosition(this.AssociatedObject); AssociatedObject.CaptureMouse(); } private void AssociatedObject_MouseMove(object sender, MouseEventArgs e) { if (isDragging) { Point point = e.GetPosition(canvas); Canvas.SetTop(AssociatedObject, point.Y - mousePoint.Y); Canvas.SetLeft(AssociatedObject, point.X - mousePoint.X); } } private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (isDragging) { AssociatedObject.ReleaseMouseCapture(); isDragging = false; } } } }