WPF点滴(3) 行为-Behavior
为了定制个性化的用户界面,我们通常会借助于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的更多相关文章
- WPF点滴(2) 创建单实例应用程序
最近有同事问道在应用程序启动之后,再次双击应用程序,如何保证不再启动新的应用程序,而是弹出之前已经启动的进程,本质上这就是创建一个单实例的WPF应用程序.在VS的工程树中有一个App.xaml和App ...
- WPF点滴
1 设置窗体的最大化,而且无边框 <Style x:Key="WindowsStyle" TargetType="Window"> <Sett ...
- [No0000124]WPF 扩展控件Behavior的几种方式
一.使用Attached Dependency Property的方式 (1)定义Attached Dependency Property public static class DigitsOnly ...
- WPF点滴(1) Main 函数
应用程序的入口函数是main函数,在Console程序和Winform程序main函数都有清晰的定义,可以很容易找到,但是WPF的工程文件中却找不到main函数的定义,是WPF不需要main函数吗?N ...
- WPF之Behavior
本文主要是以实现拖动元素作为例子. 创建Behavior: 通常这个类会继承自Behavior<T>,其中T就是此Behavior服务的对象,在此处使用的是UIElement,也就是虽有的 ...
- 【WPF】 Behavior
Hello,Behavior 引言 在看PDC-09大会的视频时,其中一篇讲利用Blend来扩展Silverlight元素的行 为,当时感觉很酷:在Blend中,将MouseDra ...
- WPF自定义行为Behavior,实现双击控件复制文本
WPF引用xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity& ...
- WPF Interaction框架简介(一)——Behavior
在WPF 4.0中,引入了一个比较实用的库——Interactions,这个库主要是通过附加属性来对UI控件注入一些新的功能,除了内置了一系列比较好用的功能外,还提供了比较良好的扩展接口.本文这里简单 ...
- WPF教程十:如何使用Style和Behavior在WPF中规范视觉样式
在使用WPF编写客户端代码时,我们会在VM下解耦业务逻辑,而剩下与功能无关的内容比如动画.视觉效果,布局切换等等在数量和复杂性上都超过了业务代码.而如何更好的简化这些编码,WPF设计人员使用了Styl ...
随机推荐
- openssl RSA基本加密解密
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <openssl/bn ...
- js网页上画图
保存 1.d3.js (http://www.d3.org/)使用svg技术,展示大数据量,动态效果很好,但是API暴露的不好,得靠自己摸索. 2.http://raphaeljs.com/refe ...
- python学习 day11 (3月16日)----(生成器内置函数)
1生成器 1生成器的本质 一定是迭代器(反之不一定(用send(生成器特有方法)验证))2生成器是可以让程序员自己定义的一个迭代器3生成器的好处,节省内存空间4生成器的特性,一次性的,惰性机制,从上往 ...
- python约束 异常 MD5 日志处理
一.约束 1.用父类执行约束 子类继承父类,用重写方法,对子类的方法进行约束. class Foo: def login(self): # 对子类进行约束,该方法需要重写 # 没有执行的错误 rais ...
- 2018.10.27 bzoj3209: 花神的数论题(数位dp)
传送门 数位dpdpdp经典题. 题面已经暗示了我们按照二进制位来数位dpdpdp. 直接dpdpdp多少个数有111个111,222个111,333个111-, 然后快速幂算就行了. 于是我们枚举前 ...
- [zhuan]SQLServer查询最近一天,三天,一周,一月,一季度方法
三天 select * from T_news where datediff(day,addtime,getdate())<= 2 and datediff(day,addtime,getdat ...
- poj-2406(字符串hash)
题目链接:传送门 思路:字符串hash,终止条件竟然判断错了,真是太大意了. #include<iostream> #include<cstdio> #include<c ...
- springboot xml声明式事务管理方案
在开发过程中springboot提供的常见的事务解决方案是使用注解方式实现. 使用注解 在启动类上添加注解 @EnableTransactionManagement 在需要事务控制的方法添加@Tran ...
- Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) D. Minimum path(字典序)
https://codeforces.com/contest/1072/problem/D 题意 给你一个n*n充满小写字母的矩阵,你可以更改任意k个格子的字符,然后输出字典序最小的从[1,1]到[n ...
- exec函数
概念 当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,新程序从main函数开始执行.调用exec并不创建新进程,所以前后的进程ID并未改变.exec只是用磁盘上的一个新程序替换了当前进 ...