一 接口分析
MVVM框架的目的就是让视图和业务逻辑分离,各干各的。那么怎样实现分离呢,精髓就是绑定ICommand。先看一下ICommand接口的定义:

//
// 摘要:
// 定义一个命令。
[TypeConverter("System.Windows.Input.CommandConverter, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")]
[TypeForwardedFrom("PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
[ValueSerializer("System.Windows.Input.CommandValueSerializer, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")]
public interface ICommand
{
//
// 摘要:
// 当出现影响是否应执行该命令的更改时发生。
event EventHandler CanExecuteChanged; //
// 摘要:
// 定义确定此命令是否可在其当前状态下执行的方法。
//
// 参数:
// parameter:
// 此命令使用的数据。 如果此命令不需要传递数据,则该对象可以设置为 null。
//
// 返回结果:
// 如果可执行此命令,则为 true;否则为 false。
bool CanExecute(object parameter);
//
// 摘要:
// 定义在调用此命令时要调用的方法。
//
// 参数:
// parameter:
// 此命令使用的数据。 如果此命令不需要传递数据,则该对象可以设置为 null。
void Execute(object parameter);
}

下面对接口中给的几个组成部分进行分析:
CanExecuteChanged:按照官方的说法是在调用CanExecute方法之前被触发
参考这个https://msdn.microsoft.com/zh-cn/library/system.windows.input.icommand.canexecutechanged.aspx

CanExecute:这个方法返回值为bool值,绑定到此命令的按钮是否可用。
这个方法在用户点击按钮后,自动触发。
Execute:这个方法就是业务逻辑的载体,用户点击按钮后,自动触发。

二 继承关系
首先需要对接口ICommand进行实现,比如叫做DelegateCommand。那么我们如何进行实现呢,把业务逻辑卸载接口的实现类里面吗?如果这样,那么每个按钮都需要定义一个ICommand的实现类了。我们引入委托的概念,把具体的的业务实现写在viewmodel类中,然后把业务实现类封装成委托交给ICommand实例来调用, 从而实现了DelegateCommand的复用。
比如下面的例子,Execute执行的是一个委托,并且把委托定义为public类型,以便于外面的viewmodel给委托进行赋值,如果不给委托赋值就代表不执行喽。

class DelegateCommand : ICommand
{
  public bool CanExecute(object parameter)
  {
    if (this.CanExecuteFunc == null)
    {
    return true;
    }     return this.CanExecuteFunc(parameter);
  }   public event EventHandler CanExecuteChanged;   public void Execute(object parameter)
  {
    if (this.ExecuteAction == null)
    {
    return;
    }
    this.ExecuteAction(parameter);
  }   public Action<object> ExecuteAction { get; set; }
  public Func<object, bool> CanExecuteFunc { get; set; }
}

  

三 ViewModel
如何编写viewmodel呢?
新建一个viewmodel类,比如:MainWindowViewModel.cs
定义一个command,如:public DelegateCommand AddCommand { get; set; }
然后再进行给command中的委托赋值,这样程序就会通过调用Execute,调用委托,达到调用viewmodel中的业务逻辑了。
比如业务逻辑方法这样写:

private void Add(object parameter)
{
this.Result = this.Input1 + this.Input2;
}

  

为command中的委托赋值:

this.AddCommand.ExecuteAction = new Action<object>(this.Add);

  

是不是有点绕呢,没错太绕了。网上有很多中写法,乱花渐欲迷人眼,但基本上都是这个意思。

四 界面绑定
先将MainWindowViewModel的实例,作为当前界面的上下文:
this.DataContext = new MainWindowViewModel();
xaml很简单,就这样一行代码
<Button x:Name="addButton" Grid.Row="3" Content="Add" Width="120" Height="80" Command="{Binding AddCommand}"/>
另外如果想再传会一个参数,可以这样写(详见demo):
Command="{Binding AddCommand}" CommandParameter="para1"

至于如何将鼠标的位置,按钮自身的信息传递到vm中,就比较复杂了,请参考其它文献。也可以在view的后台中进行处理,毕竟是界面相关的东西。

五 原理分析
那么CanExecute和Execute这两个方法是如何被调用的呢?难道是框架自己调用的吗?有一定关系,主要是和wpf绑定机制有关。当我们把一个Icommand实例绑定到界面的按钮上,点击按钮,则会触发ICommand中的方法Execute。至于为什么会触发,只能说微软自己封装的,不用我们自己来触发。

下面有两个demo仅供参考。

http://download.csdn.net/download/conganguo/10120119
---------------------
作者:12345678910dddwwwb
来源:CSDN
原文:https://blog.csdn.net/conganguo/article/details/78542968
版权声明:本文为博主原创文章,转载请附上博文链接!

WPF-MVVM-ICommand接口实现的更多相关文章

  1. [译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)

    应用不只是包含textboxs和labels,还包含actions,如按钮和鼠标事件等.接下来我们加上一些像按钮这样的UI元素来看MVVM类怎么演变的.与之前的UI相比,这次我们加上一个"C ...

  2. WPF进阶之接口(4):ICommand实现详解

    上一章WPF进阶之接口():INotifyPropertyChanged,ICommand中我们遗留了几个问题,我将在本节中做出解释.在详细解释ICommand实现之前,我们现在关注一下什么是:弱引用 ...

  3. MVVM设计模式基础知识--ICommand接口

    命令是 Windows Presentation Foundation (WPF) 中的输入机制,它提供的输入处理比设备输入具有更高的语义级别. 命令有若干用途: 第一个用途是将语义以及调用命令的对象 ...

  4. 转载:WPF MVVM之INotifyPropertyChanged接口的几种实现方式

    原文地址:http://www.cnblogs.com/xiwang/ 序言 借助WPF/Sliverlight强大的数据绑定功能,可以比实现比MFC,WinForm更加优雅轻松的数据绑定.但是在使用 ...

  5. WPF MVVM之INotifyPropertyChanged接口的几种实现方式(转)

    原地址:https://www.cnblogs.com/xiwang/archive/2012/11/25/2787358.html 序言 借助WPF/Sliverlight强大的数据绑定功能,可以比 ...

  6. WPF MVVM 学习总结(一)

    ---恢复内容开始--- 1. MVVM简介 在WPF中,MVVM(View-ViewModel-Model)开发模型用的很多,它具有低耦合,可重用行,相对独立的设计和逻辑.所以备受广大开发者的喜爱. ...

  7. WPF MVVM模式

    1. MVVM MVVM的设计模式最早于2005年由微软的WPF和Silverlight架构师John Gossman在他的博客中提到. WPF中采用MVVM的架构可以获得以下好处: 1. 将UI和业 ...

  8. WPF/MVVM 快速开始指南(译)(转)

    WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...

  9. Prism - WPF MVVM(Model-View-ViewModel)设计模式【学习】

    开发工具: VS2010 Blend Prism框架 基本概念: 数据绑定,依赖属性,依赖对象 WPF 委托式命令 Icommand接口 Lambda表达式 MVVM(Model-View-ViewM ...

  10. WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)

    到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击but ...

随机推荐

  1. 浅析Hashmap和Hashtable

    一.Hashmap不是线程安全的,而Hashtable是线程安全的 通过查看源码可以发现,hashmap类中的方法无synchronized关键字,而hashtable类中的方法有synchroniz ...

  2. 使用Spark进行搜狗日志分析实例——统计每个小时的搜索量

    package sogolog import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  3. tomcat8常用配置说明

    链接:https://www.jianshu.com/p/8b1c75951f70 2.tomcat8运行期错误HTTP头解析错误 修改tomcat的server.xml中的中配置  设置为8k &l ...

  4. eclipse Android项目 DDMS db文件 导出 Failed to pull selection null 问题

    我在 eclipse的Android项目中,在 DDMS导出db文件 时,发现报错:Failed to pull selection null 在左侧选中设备,在进行导出 这样就可以正常的进行导出db ...

  5. css中width:auto和width:100%的区别是什么

    width的值一般是这样设置的: 1,width:50px://宽度设为50px 2,width:50%://宽度设为父类宽度的50% 3,还有一个值是auto(默认值),宽度是自动的,随着内容的增加 ...

  6. java基础知识—字符串

    1.声明字符串的方法: String s ="你好" String s=new String("你好"); 2.字符串的长度: 字符串.length(); 3. ...

  7. 最近学习了Sqlite3数据库,写一下操作应用以及命令

    首先使用Flask-SQLAlchemy管理数据库 使用pip安装:pip install flask-sqlalchemy 接着要配置数据库,定义模型 关于数据库的操作就不再写了.... 使用Fla ...

  8. java知识点总结--java数据类型

    java中的两大数据类型 1.基本数据类型:也称作内置类型,java语言本身提供的基本数据类型是其他类型(包括java核心类和用户自定义类)的基础 2.引用数据类型:java语言根据基本类型扩展数的其 ...

  9. Windows下杀掉全部的子线程

    最近遇到一个问题,就是在Windows下怎么杀掉全部的子线程,现把解决方法记录下. 问题来源: 用python执行了一个bat脚本,脚本的内容是执行一系列的adb命令,然后运行一个server.其中需 ...

  10. 安装mingw编译器

    1.下载地址:https://sourceforge.net/projects/mingw/files/latest/download?source=top3_dlp_t5 2. 安装下载的(ming ...