以前的做法:

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层事件的响应的更多相关文章

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

    话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...

  2. [WPF系列]-使用Binding来同步不同控件的Dependency property

    简介 项目中经常会用到,同步两个控件的值,本文就简单列举两种方式来同步不同控件的两个Dependency Property. 示例 效果图: 只使用C#代码: //获取slider1的ValueDep ...

  3. WPF系列教程——(二)使用Prism实现MVVM设计模式 - 简书

    原文:WPF系列教程--(二)使用Prism实现MVVM设计模式 - 简书 本文假设你已经知道MVVM设计模式是什么,所以直接进入正题,今天我们就用Prism来实现WPF的MVVM设计模式,百度上关于 ...

  4. WPF基础知识、界面布局及控件Binding(转)

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  5. WPF基础知识、界面布局及控件Binding

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

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

    原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们 ...

  7. WPF 实现跑马灯效果的Label控件,数据绑定方式实现

    原文:WPF 实现跑马灯效果的Label控件,数据绑定方式实现 项目中需要使用数据绑定的方式实现跑马灯效果的Label,故重构了Label控件:具体代码如下 using System; using S ...

  8. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探         最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...

  9. WPF 程序如何移动焦点到其他控件

    原文:WPF 程序如何移动焦点到其他控件 WPF 中可以使用 UIElement.Focus() 将焦点设置到某个特定的控件,也可以使用 TraversalRequest 仅仅移动焦点.本文介绍如何在 ...

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

    做过网页的人都知道,html表单控件十分重要.基本上我们注册会员.登录用户,都需要填写用户名.密码,那些框框都是表单控件. 本来今天就想写一些常用的html表单控件,于是开始搜资料,找到了一个网页,作 ...

随机推荐

  1. 算法笔记(c++)--使用一个辅助栈排列另一个栈

    算法笔记(c++)--使用一个辅助栈排列另一个栈 仅仅使用一个辅助栈,不使用其他数据结构来排列一个栈,要求,上大下小. 分析下.肯定是先吧主栈中的数据都放到辅助栈中,在辅助栈中上小下大. 1.首先循环 ...

  2. SpringMVC Controller介绍及常用注解——@Controller

    一 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model ...

  3. 腾讯视频qlv格式转换MP4普通视频方法

    QLV格式视频不是那么好对付的,似乎是一种加密格式,试着把.qlv改成.mp4或.flv都没有用,用格式工厂等转换软件转换也根本无法识别.但这并不意味着没有办法,其实真正的方法是不用任何工具: 1,我 ...

  4. Appstate的几种状态及在android 和ios触发

    AppState能告诉你当前应用是在前台还是在后台,或者处于切换应用的状态,并且能在状态变化的时候通知你. AppState 通常在处理推送通知的时候用来决定内容和对应的行为 一: App State ...

  5. Play on Words(欧拉回路)

    Description Some of the secret doors contain a very interesting word puzzle. The team of archaeologi ...

  6. psp项目计划

    日期/任务 听课 编写程序 阅读书籍 查阅资料 日总计 周一 2h 0.5h     2.5 周二     1h   1 周三     1h     周四 2h 0.5h     2.5 周五   3 ...

  7. plsql 永久注册码

    注册码:Product Code:4t46t6vydkvsxekkvf3fjnpzy5wbuhphqzserial Number:601769 password:xs374ca 可用

  8. 第5章 Linux 常用网络指令

    网络参数设定使用的指令 手动/自动设定与启动/关闭 IP 参数: ifconfig, ifup, ifdown ifconfig :查询.设定网络卡与 IP 网域等相关参数:ifup, ifdown: ...

  9. bl bl bl bl bl

    package com.dh.activiti; import org.springframework.web.servlet.HandlerInterceptor; import org.sprin ...

  10. linux普通用户被内存被限制的问题

    把应用从root用户迁移到普通用户test,由于普通用户会被限制最大的进程数,当进程数占满后出现了下面的错误 /bin/bash: Resource temporarily unavailable. ...