为了定制个性化的用户界面,我们通常会借助于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. 微信JSSDK接口previewImage

    <div class="pics"> <img src="http://pic1.ytqmx.com:82/2015/0409/01/15.jpg!96 ...

  2. C# WebService创建、发布、调用的简单例子

    Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布式的互操作的应用程序. Web ...

  3. 【C#】详解C#委托

    目录结构: contents structure [+] 委托语法 泛型委托 委托链 lambda表达式 揭秘委托 类库中的委托 委托和反射 1.委托语法 本文会详细阐述委托的使用,以及实现,想必读者 ...

  4. springMVC学习三 注解开发环境搭建

    第一步:导入jar包 第二步:配置DispatcherServlet  前端控制器 因为此处把DsipatcherServlet的映射路径配置成了"/",代表除了.jsp文件之外, ...

  5. 斐波那契数列(NOIP1997)

    题目链接:斐波那契数列 这题是数论的一个基本应用,还是很水,因为数据范围太水了,只有48,这也太小了.不过也有可能是当时的电脑速度跑得比较慢的原因.但是这个算法应该还是这个算法.主要思路就是递推求斐波 ...

  6. ubuntu下安装/卸载vmware虚拟机

    1.下载vmware(官网下载试用版,试用版输入序列号后即为专业版,序列号网上搜,很多) 2.下载后安装(命令行) 1)cd进你下载的位置 1.1)下载的文件名字为:VMware-Workstatio ...

  7. 制作centos sshd 镜像

    [root@b5926410fe60 /]# yum install passwd openssl openssh-server -y 启动sshd: # /usr/sbin/sshd -D 这时报以 ...

  8. 2018.11.01 NOIP训练 递增数列(迭代加深)

    传送门 直接迭代加深搜索. 发现每次最多增加一倍,最少增加一,于是果断上下界剪枝. 代码

  9. 走进JDK(三)------AbstractStringBuilder、StringBuffer、StringBuilder

    AbstractStringBuilder是一个抽象类,StringBuffer.StringBuilder则继承AbstractStringBuilder,所以先说AbstractStringBui ...

  10. bootstrap-glyph-customization

    http://www.runoob.com/try/demo_source/bootstrap-glyph-customization.htm http://fontawesome.io/icons/