WPF系列之二:解耦View层控件事件与ViewModel层事件的响应

以前的做法:

1.当项目的时间比较紧迫的时候,对UI层中控件的事件的处理,往往采取的是类似Winform中最简单的做法,直接做一个事件的Handler直接去调用VM层的方法。

2.控件只有一个Command属性,其它的事件的处理方法没有办法和ViewModel层进行解耦的时候往往也采取上面提到的方法。

如下图所示:

新的做法:

为了实现事件的处理与View层的解耦,我们可以利用WPF提供的附加属性来为需要的事件添加附加行为。附加属性扮演了一个在View层与Model层牵线的角色。

需要下面三个步骤来实现(以Load事件为例):

1.在ViewModel中定义一个Command属性

 winloadedCommand = new DelegateCommand(this.executeWinloadedCommand, this.canWinloadedCommand);

实例化Command

定义ICommand类型的command

 #region
private ICommand winloadedCommand;
public ICommand WinloadedCommand
{
get { return winloadedCommand; }
set
{
if (winloadedCommand != value)
{
winloadedCommand = value;
OnPropertyChagned("WinloadedCommand");
}
}
}
private void executeWinloadedCommand()
{
CalculatingStatus = "The WinloadedCommand has been called!";
}
private bool canWinloadedCommand()
{
return true;
}
#endregion

WinloadedCommand

2.定义一个CommandBehaviors类,在其中定义一个ICommand类型的附加属性,并在PropertyChangedCallback的回调中链接事件与实际的command实例之间的调用。

public static class CommandBehaviors
{
public static ICommand GetWindowLoadCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(WindowLoadCommandProperty);
}
public static void SetWindowLoadCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(WindowLoadCommandProperty, value);
}
// Using a DependencyProperty as the backing store for WindowLoadCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WindowLoadCommandProperty =
DependencyProperty.RegisterAttached("WindowLoadCommand", typeof(ICommand), typeof(CommandBehaviors), new PropertyMetadata(null, OnWindowLoadedCommandPropertyChanged));
public static void OnWindowLoadedCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var frameworkElement = d as FrameworkElement;
if (frameworkElement != null && e.NewValue is ICommand)
{
frameworkElement.Loaded
+= (obj, args) =>
{
if ((e.NewValue as ICommand).CanExecute(obj))
{
(e.NewValue as ICommand).Execute(null);
}
};
}
}
}

CommandBehaviors

3.在xaml中进行Binding

大功告成,运行示例如下:

思考1:如何实现带有参数的调用?Event-〉Command

1.如果参数数据来源于控件本身的属性,可以在链接Event与Command时直接传递参数

2.如果数据来自外界,可以在CommandBehaviors类中定义额外的附加属性,然后将参数绑定到此属性上面,当调用command时,检查该属性。

完毕。

作者:Andy Zeng

欢迎任何形式的转载,但请务必注明出处。

http://www.cnblogs.com/andyzeng/p/3708276.html

WPF系列之二:解耦View层控件事件与ViewModel层事件的响应,布布扣,bubuko.com

时间: 2024-10-07 07:13:48

WPF系列之二:解耦View层控件事件与ViewModel层事件的响应的相关文章

WPF自定义控件(二)の重写原生控件样式模板

开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么办呢?----自定义样式与模板. 一.样式 在WPF中我们可以使用Style来设置控件的某些属性值,并使该设置影响到指定范围内的所有该类控件或影响指定的某一控件,比如说我们想将窗口中的所有按钮都保持某一种风格,那么我们可以设置一个Style,而不必分别设置每个按钮的风格.Style是作为一种资源被保存下来的. 看下面的例子: <Style x:Key="style1" T

【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法

原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们并不想在DataHolder类中加一个标识是否选中的checked的成员变量,因为在项目开发中,大部分的ListItemLayout布局都是大家共用的,有些人根本不需要checkbox控件,所以会在初始化的时候把这个控件给隐藏掉,但我们的DataHolder在构造的时候以及ListItemAdapt

我教女朋友学编程Html系列(6)—Html常用表单控件

做过网页的人都知道,html表单控件十分重要.基本上我们注册会员.登录用户,都需要填写用户名.密码,那些框框都是表单控件. 本来今天就想写一些常用的html表单控件,于是开始搜资料,找到了一个网页,作者的写作思路和我的基本相同,不过不足的是缺少效果图. 我打算结合着这位仁兄的文章补充一下,增加一些效果图,另外把一些新内容也补充进去,原文的地址是: HTML表单(Forms) 我站在这位仁兄的肩膀上写作,再增加一些东西,配上一些图,我想,效果应该很好,接着就跟着我来学习吧. HTML表单(Form

ASP.NET—013:实现带控件的弹出层(弹出框)

在页面中用到弹出新页面的情况比较多的,一般来说都是使用JS方法showModalDialog("新页面相对路径+?参数1&参数2",window,"新页面样式");然后会新弹出一个模态的page页.而在有些时候,仅仅是显示一些单一的.少量的数据,或者一些简单的操作时.就没必要使用新弹出页面了.此时,最好使用弹出层,也就是数据还是显示在当前页面的某个控件上,然后通过JS方法实现达到弹出的目的.看下面的例子: <html xmlns="http:

【WPF学习】第十九章 控件类

原文:[WPF学习]第十九章 控件类 WPF窗口充满了各种元素,但这些元素中只有一部分是控件.在WPF领域,控件通常被描述为与用户交互的元素--能接收焦点并接受键盘或鼠标输入的元素.明显的例子包括文本框和按钮.然而,这个区别有时有些模糊.将工具提示视为控件,因为它根据用户鼠标的移动显示或消失.将标签视为控件,因为它支持记忆码(mnemonics,将焦点转移到相关控件快捷键). 所有控件都继承自System.Windows.Control类,该类添加了一小部分基本的基础结构: 设置控件内容对齐方式

WPF中嵌入WinForm中的webbrowser控件

原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能使用.决定还是使用WinForm中的webbrowser.要想在WPF中使用WinForm控件,查看MSDN,需经过以下步骤. 创建名为 HostingWfInWpf 的 WPF 应用程序项目. 在解决方案资源管理器中,添加一个对名为 WindowsFormsIntegration.dll 的 Wi

winform学习日志(二十六)----------控件treeview使用

一:实现功能,获得选中节点,在选中节点下添加节点,折叠,展开,删除,得到选中节点下checked项,选中根节点其下节点也选中,图标.上图 二:相关代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windo

《Programming WPF》翻译 第5章 7.控件模板

原文:<Programming WPF>翻译 第5章 7.控件模板 如果仔细的看我们当前的TTT游戏,会发现Button对象并没有完全为我们工作.哪些TTT面板有内圆角? 图5-14 这里,我们真正需要的是能够保持按钮的行为,如支持内容和点击事件,但是我们想要接管这些按钮的外观.WPF允许这种方式,因为内在的控件创建的时候是缺少外观性的,例如,他们提供行为,但是外观可以被完全包装在客户端控件的外面. 还记得我们是如何使用数据模板,来为非可视化对象提供外观的么?我们能够使用控件模板对控件做同样的

基于jquery扩展的弹层控件

漂亮且超好用的弹出层事件类JS代码,支持各种对话框.弹出层等,弹出层可拖拽移动且拖拽流畅,浏览器兼容良好.可自定义内容.标题.宽高.按钮.和绑定相对应的事件简单方便的实现弹层,实现添加数据或显示详细信息等功能. 下面跟着我的步伐走 (1)准备好要显示的内容,这不仅仅是内容,也可以是html代码 (2)准备好内容之后,要记得给它取个响亮的标题,明确下主题,当然也可以不需要 (3)是不是觉得有些时候确定和取消这两个家伙没必要出现,如果不用它们可以将舍弃,不填他们就好了 是不是很简单,还在等什么,快来