WPF实现Interaction框架的Behavior扩展

WPF实现Interaction框架的Behavior扩展

在WPF 4.0中,引入了一个比较实用的库——Interactions,这个库主要是通过附加属性来对UI控件注入一些新的功能,除了内置了一系列比较好用的功能外,还提供了比较良好的扩展接口。本文这里简单的介绍一下Behavior这个扩展。

顾名思义,Behavior可以赋予控件新的行为能力,例如,我们可以通过MouseDragElementBehavior给控件附加上支持拖放的能力。使用方式如下:

添加Interactions库的引用。主要添加如下两个DLL:Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll。添加如下名字空间

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"在控件中添加MouseDragElementBehavior <Image Source="2.webp" > <i:Interaction.Behaviors> <ei:MouseDragElementBehavior/> </i:Interaction.Behaviors> </Image>

 这三步中前面几步都是添加Interactions库的支持,对于后面介绍的Trigger和Action也是一样的,只有<ei:MouseDragElementBehavior/>一句才是和Behavior相关的。实际上,我们可以通过在Blend里直接将MouseDragElementBehavior拖放到控件上简化这一过程。加上MouseDragElementBehavior后,我们的控件就支持鼠标拖拽移动了,非常给力。

实际上,系统还提供了一系列非常好用的Behavior,后面我再单独写文章来介绍它。 

编写自己的Behavior

除了系统自己提供的Behavior外,我们也可以通过自己编写Behavior来实现自定义行为,一个简单的示例如下:  

class SkewBehavior : Behavior<UIElement> { SkewTransform _transForm; protected override void OnAttached() { base.OnAttached(); _transForm = new SkewTransform(); AssociatedObject.RenderTransform = _transForm; AssociatedObject.RenderTransformOrigin = new Point(0.5, 0.5); _transForm.AngleX = 30; } protected override void OnDetaching() { _transForm.AngleX = 0; base.OnDetaching(); } }

上面的代码同样实现了一个将控件水平方向倾斜30度的Behavior(实现得比较简单,并不完善),大体上关键的地方有如下三个:

通过AssociatedObject属性获取附加的对象。通过重载OnAttached函数进行Behavior附加上时的初始化操作通过重载OnDetaching函数进行移除Behavior时候的析构操作

虽然我们也可以直接通过附加属性实现这样的功能,但Interactions框架无疑规范并简化了这一行为。

最后,附上一个比较常用的鼠标拖放的Behavior,和内置的MouseDragElementBehavior不同的是,它产生鼠标事件,用于实现一些自定义的拖放操作:

class DragDropBehavior : Behavior<UIElement> { public event EventHandler<DragDeltaEventArgs> DragDelta; public event EventHandler<EventArgs> Drop; IInputElement _parent; protected override void OnAttached() { base.OnAttached(); _parent = LogicalTreeHelper.GetParent(AssociatedObject) as IInputElement; if (_parent == null) return; AssociatedObject.MouseLeftButtonDown += onMouseDown; AssociatedObject.MouseMove += onMouseMove; AssociatedObject.MouseLeftButtonUp += onMouseUp; AssociatedObject.MouseEnter += onDragEnter; } protected override void OnDetaching() { AssociatedObject.MouseLeftButtonDown -= onMouseDown; AssociatedObject.MouseMove -= onMouseMove; AssociatedObject.MouseLeftButtonUp -= onMouseUp; AssociatedObject.MouseEnter -= onDragEnter; base.OnDetaching(); } Point? start; private void onMouseDown(object sender, MouseButtonEventArgs e) { start = Mouse.GetPosition(_parent); } private void onMouseMove(object sender, MouseEventArgs e) { if (!start.HasValue) return; var p = Mouse.GetPosition(_parent); var offset = p - start.Value; start = p; DragDelta?.Invoke(AssociatedObject, new DragDeltaEventArgs(offset.X, offset.Y)); } private void onMouseUp(object sender, MouseButtonEventArgs e) { tryEndDrag(); } private void onDragEnter(object sender, MouseEventArgs e) { tryEndDrag(); } void tryEndDrag() { if (Mouse.LeftButton != MouseButtonState.Released) return; start = null; Drop?.Invoke(AssociatedObject, EventArgs.Empty); } }

推荐阅读

    wpf快捷键设置|wpf 右键菜单

    wpf快捷键设置|wpf 右键菜单,,wpf快捷键设置1.如果点击启动游戏后,游戏窗口弹不出来,可以尝试把客户端(连同配置一起)完全删除,重新下载客户端

    wpa隐藏快捷键|wpf快捷键设置

    wpa隐藏快捷键|wpf快捷键设置,,1. wpf快捷键设置1.如果点击启动游戏后,游戏窗口弹不出来,可以尝试把客户端(连同配置一起)完全删除,重新下载客

    在 WPF 中使用 SQLite

    在 WPF 中使用 SQLite,配置文件,代码, 对于一般的WINFORM或者WEB程序,网上已经有了解决方案:只需要在应用程序配置文件configuration节点加

    wpf界面风格|wp风格主题

    wpf界面风格|wp风格主题,,1. wpf界面风格wpf释义:abbr. 用于为不同用户界面提供统一的显示系统( Windows Presentation Foundation)例句:WPF i

    WPF Datatrigger不会在预期时触发

    WPF Datatrigger不会在预期时触发,WPF Datatrigger不会在预期时触发,显示,文本,变化,第一个,WPF Datatrigger not firing when expected我

    如何使用NAnt编译WPF控件

    如何使用NAnt编译WPF控件,如何使用NAnt编译WPF控件,控件,编译,脚本,项目,How can I use NAnt to compile WPF controls我有一个WPF项目,我正

    关于动画:WPF数据触发器和故事板

    关于动画:WPF数据触发器和故事板,关于动画:WPF数据触发器和故事板,属性,动画,模型,我都,WPF Data Triggers and Story Boards每当ViewModel /