有种想写一个MVVM框架的冲动!!!

1、Model中的属性应不应该支持OnPropertyChanged事件?


不应该。应该有ViewModel对该属性进行封装,由ViewModel提供OnPropertyChanged事件。WPF之MVVM(1)中有实例

2、如何将控件事件转换为命令?


  • 在“扩展”中添加“System.Windows.Interractivity”引用
  • xaml中添加xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity命名空间
  • 使用

    <ListBox Name="LbBox" ItemsSource="{Binding Path=SourceCount}">
    <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
    <common:ExInvokeCommandAction Command="{Binding Path=SelectionChangedCmd}" CommandParameter="{Binding ElementName=LbBox, Path=SelectedItem}"/>
    </i:EventTrigger>
    </i:Interaction.Triggers>
    </ListBox>

3、View中如何访问ViewModel


WPF之MVVM(2)中介绍了

4、ViewModel中如何访问View


WPF之MVVM(2)中介绍了

5、ViewModel之间通信


  • 聚合关系

    public class VM01
    {
    public string Name{get;set;}
    } public class VM02
    {
    public list<VM01> Property
    {
    get;
    set;
    }
    }
  • 组合关系

    public class VM01
    {
    public string Name{get;set;}
    } public class VM02
    {
    public string Name{get;set;}
    } public class VM03
    {
    private VM01 _vm01;
    private VM02 _vm02;
    ...
    public VM03(VM01 vm01, VM02 vm02){}
    }
  • 依赖关系

这里主要介绍下依赖关系的ViewModel如何通信

通过一个非常简单的程序来演示这种实现:点击左边的数字,右边的数字加1。

左边为LeftViewModel右边为RightViewModel,两个VM是相互独立的,通过事件进行通信。

1、定义类型来容纳所有需要发送给事件通知接收者的附件信息

public class NumberChangedEventArgs : EventArgs
{
public int Number { get; set; } public NumberChangedEventArgs(int num)
{
Number = num;
}
}

2、在LeftViewModel中定义事件成员

public event EventHandler<NumberChangedEventArgs> NumberChanged;

protected virtual void OnNumberChanged(NumberChangedEventArgs e)
{
var handler = NumberChanged;
if (handler != null) handler(this, e);
}

3、定义负责引发事件的方法来通知事件的登记对象

/// <summary>
/// 选择命令
/// </summary>
private DelegateCommand<ExCommandParameter> _selectionChangedCmd; public DelegateCommand<ExCommandParameter> SelectionChangedCmd
{
get
{
if (_selectionChangedCmd == null)
{
_selectionChangedCmd = new DelegateCommand<ExCommandParameter>(InvokeMouseDown);
} return _selectionChangedCmd;
}
} private void InvokeMouseDown(ExCommandParameter param)
{
var number = param.Parameter is int ? (int) param.Parameter : ;
//触发事件
OnNumberChanged(new NumberChangedEventArgs(number));
}

4、定义方法将输入转化为期望事件

public class RightViewModel : ViewModelBase
{
public RightViewModel()
{
//订阅事件
var vm = ViewModelManager.GetByKey("left") as LeftViewModel;
if (vm != null) vm.NumberChanged += VmOnNumberChanged;
} private int _number; public int Number
{
get { return _number; }
set
{
_number = value;
OnPropertyChanged("Number");
}
} /// <summary>
/// 事件处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void VmOnNumberChanged(object sender, NumberChangedEventArgs e)
{
Number = e.Number + ;
}
}

问题RightViewModel中如何获取LeftViewModel呢?

定义一个容器

public static class ViewModelManager
{
private static readonly Dictionary<string, ViewModelBase> Dic = new Dictionary<string, ViewModelBase>(); public static void Add(string key, ViewModelBase value)
{
if (Dic.ContainsKey(key)) return; Dic.Add(key, value);
} public static ViewModelBase GetByKey(string key)
{
if (!Dic.ContainsKey(key)) return null; ViewModelBase value;
Dic.TryGetValue(key, out value); return value;
}
}

在设置View的DataContext时将ViewModel添加到ViewModelManager

public LeftView()
{
InitializeComponent(); var vm = new LeftViewModel();
ViewModelManager.Add("left", vm);
this.DataContext = vm;
}

总结


回顾上面3篇博文中解决的问题,我们再来看下MvvmLight ToolKit是如何实现MVVM的,这里引用下园友的总结MvvmLight ToolKit 教程

我们可以猜测MvvmLight作者使用这些组件是为了解决什么问题?

  • ViewModelBase && ObservableObject(INotifyPropertyChanged接口的实现,解决属性改变通知的问题)
  • ViewModelLocator && SimpleIoc(IOC容器,我们的ViewModelManager高级版)
  • RelayCommand(ICommand接口的实现,解决View和ViewModel通信问题)
  • EventToCommand && IEventArgsConverter(Interaction的封装,解决将事件转换为命令的问题)
  • Messenger(解决View和ViewModel以及ViewModel和ViewModel之间通信的问题)
  • DispatcherHelper(博客中未提到)

这样分析后,我们就知道MvvmLight是如何产生的,以及它能为我们做什么。

吹牛吹到现在,我都有种自己想写一个MVVM框架的冲动了。你们有没有?

WPF之MVVM模式(3)的更多相关文章

  1. 【WPF】MVVM模式的3种command

    原文:[WPF]MVVM模式的3种command 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL, ...

  2. WPF之MVVM模式讲解

    WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI. 恰当的模式可以让我们轻松达到“高内聚 ...

  3. 【转】【WPF】MVVM模式的3种command

    1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL,所以这3种模式中也有一些小差异,比如RelayCo ...

  4. WPF之MVVM模式(2)

    我们都想追求完美 Every view in the app has an empty codebehind file, except for the standard boilerplate cod ...

  5. WPF之MVVM模式(1)

    MVVM模式 一.MVVM模式概述 MVVM Pattern : Model\View\ViewModel View:视图.UI界面 ViewModel:ViewModel是对Model的封装,通过一 ...

  6. WPF中MVVM模式的 Event 处理

    WPF的有些UI元素有Command属性可以直接实现绑定,如Button 但是很多Event的触发如何绑定到ViewModel中的Command呢? 答案就是使用EventTrigger可以实现. 继 ...

  7. WPF中 MVVM模式的Slider Binding.

    对于Button的Command的绑定可以通过实现ICommand接口来进行,但是Slider并没有Command属性. 另外如果要实现MVVM模式的话,需要将一些Method和Slider的Even ...

  8. WPF采用MVVM模式(绑定:纯前台、命令:触发器绑定命令)

    MVVM绑定 view-viewModel-model,模型介绍省略,就是创建类,添加字段封装属性.注:控件的绑定只能绑定到属性上,不能绑定到字段上: 接下来就是代码 (view): <Wind ...

  9. WPF中MVVM模式下控件自有的事件绑定

    1.原因 在WPF中单纯的命令绑定往往不能满足覆盖所有的事件,例如ComboBox的SelectionChanged事件,DataGrid的SelectionChanged事件等等,这时就可以用事件绑 ...

随机推荐

  1. python实现进程的并发

    __author__ = 'luozt' import telnetlib import multiprocessing import random def telnet(ip,hostname): ...

  2. VC 6.0下载 VC 6.0英文版下载 Visual C++ 6.0 英文企业版 集成SP6完美版(最新更新地址,百度网盘)

    下载地址1:Visual.C++.6.EN 下载地址2:Visual.C++.6.EN 更新下载地址可用(百度网盘)Visual.C++.6.EN 转载请注明出处,有技术问题,欢迎互相交流,或者留言.

  3. Kerberos的hive链接问题

    javax.security.auth.login.LoginException: Checksum failed 之前碰到过类似的问题,都是因为服务器端的keytab问题:多半是因为重新生成了key ...

  4. Hive的JDBC访问引发的Maven依赖的实践

    invalid LOC header (bad signature) 原来是因为依赖问题,直接依赖“hive-server”的见解依赖jetty-all有冲突:诡异的是在main方法中执行是OK的,但 ...

  5. DOM对象和JQuery对象互转

    实现点击某一个单元格,将单元格内部的sql提交执行: <td onclick="submitSqlExecute(this)">...<span>${ctx ...

  6. C# 常用文件操作

    public class IoHelper { /// <summary> /// 判断文件是否存在 /// </summary> /// <param name=&qu ...

  7. PAT 垃圾箱分布(30分)dijstra

    垃圾箱分布 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾 ...

  8. springmvc----demo---login---bai

    web.xml配置: <?xml version="1.0" encoding="UTF-8"?> <web-app version=&quo ...

  9. Apache Geronimo Remote Code Execute Vulnerability

    简介: Apache Geronimo 是 Apache 软件基金会的开放源码J2EE服务器,它集成了众多先进技术和设计理念. 这些技术和理念大多源自独立的项目,配置和部署模型也各不相同. Geron ...

  10. opencv 美白磨皮人脸检测<转>

    1. 简介 这学期的计算机视觉课,我们组的课程项目为“照片自动美化”,其中我负责的模块为人脸检测与自动磨皮.功能为:用户上传一张照片,自动检测并定位出照片中的人脸,将照片中所有的人脸进行“磨皮”处理, ...