为了定制个性化的用户界面,我们通常会借助于WPF强大的样式(style),修改控件属性,重写控件模板(template),样式帮助我们构建一致的个性化控件。通过样式可以调整界面的显示效果,这只是界面构成的一部分,界面有很多功能是与程序功能无关的,比如停靠、拖动、缩放等,这些通用的功能要如何实现呢,所有用到的地方都单独实现肯定是不现实的,行为(behavior)这时就可以大展拳脚了。

什么是行为,行为是为控件封装好的功能。你可以为Image控件封装缩放行为,或者为所有控件(UIElement)封装拖动行为,后面有例子。

行为(Behavior)不是基础WPF的一部分,他是作为Expression Blend的设计特性而引入的,因此使用Behavior时需要手动添加reference,C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.5\Libraries\System.Windows.Interactivity.dll,安装完visual studio就会有这个文件啦。

现在开始封装一个行为,实现控件在Canvas面板上的拖拽。Behavior是一个模板类,封装控件的行为只需要继承Behavior<T>就可以了,T为控件的类型,这里要为所有控件封装拖拽行为,因此使用了UIElement。

需要重载 OnAttached和OnDetaching方法,其中AssociatedObject指的是封装了该行为的控件。

using System.Windows.Interactivity;

public class DragInCanvsBehavior : Behavior<UIElement>
{
private Canvas m_Canvas;
private bool m_IsDraging;
private Point m_PositionOffset; protected override void OnAttached()
{
base.OnAttached(); AssociatedObject.MouseLeftButtonDown += AssociatedObjectOnMouseLeftButtonDown;
AssociatedObject.MouseMove += AssociatedObjectOnMouseMove;
AssociatedObject.MouseLeftButtonUp += AssociatedObjectOnMouseLeftButtonUp;
} private void AssociatedObjectOnMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
if (m_Canvas == null)
m_Canvas = (Canvas)VisualTreeHelper.GetParent(AssociatedObject); m_IsDraging = true; m_PositionOffset = mouseButtonEventArgs.GetPosition(AssociatedObject);
AssociatedObject.CaptureMouse();
} private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
if(!m_IsDraging)
return; Point mouseposition = mouseEventArgs.GetPosition(m_Canvas);
AssociatedObject.SetValue(Canvas.LeftProperty, mouseposition.X - m_PositionOffset.X);
AssociatedObject.SetValue(Canvas.TopProperty, mouseposition.Y - m_PositionOffset.Y);
} private void AssociatedObjectOnMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
if (!m_IsDraging)
return; m_IsDraging = false;
AssociatedObject.ReleaseMouseCapture();
} protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.MouseLeftButtonDown -= AssociatedObjectOnMouseLeftButtonDown;
AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove;
AssociatedObject.MouseLeftButtonUp -= AssociatedObjectOnMouseLeftButtonUp;
}
}

使用Behavior的方法如下,这时就会得到一个可以拖动的矩形了。

<Window x:Class="BehaviorDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BehaviorDemo"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Rectangle Height="40" Width="80" Canvas.Left="100" Canvas.Top="50" Fill="Aqua">
<i:Interaction.Behaviors>
<local:DragInCanvsBehavior/>
</i:Interaction.Behaviors>
</Rectangle> <Ellipse Height="40" Width="80" Fill="AntiqueWhite"/>
</Canvas>
</Window>

在i:Interaction下面除了Behavior之外,还可以定义Triggers,但是这个触发器和样式(style)中的触发器(Trigger)可不是同一个东西,这个触发器是为Silverlight准备的,因为silverlight不支持样式触发器,因此如果使用WPF,就不用关注这部分了。

WPF点滴(3) 行为-Behavior的更多相关文章

  1. WPF点滴(2) 创建单实例应用程序

    最近有同事问道在应用程序启动之后,再次双击应用程序,如何保证不再启动新的应用程序,而是弹出之前已经启动的进程,本质上这就是创建一个单实例的WPF应用程序.在VS的工程树中有一个App.xaml和App ...

  2. WPF点滴

    1 设置窗体的最大化,而且无边框 <Style x:Key="WindowsStyle" TargetType="Window"> <Sett ...

  3. [No0000124]WPF 扩展控件Behavior的几种方式

    一.使用Attached Dependency Property的方式 (1)定义Attached Dependency Property public static class DigitsOnly ...

  4. WPF点滴(1) Main 函数

    应用程序的入口函数是main函数,在Console程序和Winform程序main函数都有清晰的定义,可以很容易找到,但是WPF的工程文件中却找不到main函数的定义,是WPF不需要main函数吗?N ...

  5. WPF之Behavior

    本文主要是以实现拖动元素作为例子. 创建Behavior: 通常这个类会继承自Behavior<T>,其中T就是此Behavior服务的对象,在此处使用的是UIElement,也就是虽有的 ...

  6. 【WPF】 Behavior

    Hello,Behavior   引言         在看PDC-09大会的视频时,其中一篇讲利用Blend来扩展Silverlight元素的行 为,当时感觉很酷:在Blend中,将MouseDra ...

  7. WPF自定义行为Behavior,实现双击控件复制文本

    WPF引用xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity& ...

  8. WPF Interaction框架简介(一)——Behavior

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

  9. WPF教程十:如何使用Style和Behavior在WPF中规范视觉样式

    在使用WPF编写客户端代码时,我们会在VM下解耦业务逻辑,而剩下与功能无关的内容比如动画.视觉效果,布局切换等等在数量和复杂性上都超过了业务代码.而如何更好的简化这些编码,WPF设计人员使用了Styl ...

随机推荐

  1. centos配置虚拟用户再也不用那么麻烦了

    http://wiki.centos.org/HowTos/Chroot_Vsftpd_with_non-system_users yum install -y vsftpd db4-utils vs ...

  2. Ubuntu显示实时网速CPU内存等参数

    添加库 sudo add-apt-repository ppa:fossfreedom/indicator-sysmonitor 更新软件列表 sudo apt-get update 安装indica ...

  3. 2018.12.22 bzoj3473: 字符串(后缀自动机+启发式合并)

    传送门 调代码调的我怀疑人生. 启发式合并用迭代写怎么都跑不过(雾 换成了dfsdfsdfs版本的终于过了233. 题意简述:求给出nnn个字串,对于每个给定的字串求出其有多少个字串在至少kkk个剩下 ...

  4. 2018.11.06 bzoj2287: 【POJ Challenge】消失之物(背包)

    传送门 先假设所有物品都能用,做01背包求出方案数. 然后枚举每个点,分类讨论扣掉它对答案的贡献. 代码: #include<bits/stdc++.h> using namespace ...

  5. ThinkPHP redirect 传参

    重定向带参 $this->redirect('pay/under_line_success',array('order_id'=>$stuInfo),5,'页面跳转中….'); 第一个参数 ...

  6. mysql only_full_group_by报错的问题(转)

    原文:https://www.cnblogs.com/jim2016/p/6322703.html 在mysql 工具 搜索或者插入数据时报下面错误: ERROR 1055 (42000): Expr ...

  7. 4-具体学习git--分支

    图形的方式显示日志:git log --oneline --graph 两种方式建立分支: 1.git branch dev,建立一个dev的分支 git branch 查看分支有哪些,星号在当前分支 ...

  8. JDK 1.5、1.6 & 中文版API,J2EE5API大全(借鉴)

    个人分类: Java文档           Sun 公司提供的Java API Docs是学习和使用Java语言中最经常使用的参考资料之一.但是长期以来此文档只有英文版,对于中国地区的Java开发者 ...

  9. screen对象和history对象

    history对象保存着用户上网的历史记录,从窗口被打开的那一刻开始算起 使用go()方法可以在用户的历史记录中任意跳转 history.go(-1);//后退一页 history.go(1);//前 ...

  10. oracle忘记了sys,system 密码后怎么修改?

    一.忘记除SYS.SYSTEM用户之外的用户的登录密码.  用SYS (或SYSTEM)用户登录: CONN SYS/PASS_WORD AS SYSDBA;  使用如下语句修改用户的密码: ALTE ...