WPF之MVVM模式(3)
有种想写一个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
4、ViewModel中如何访问View
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)的更多相关文章
- 【WPF】MVVM模式的3种command
原文:[WPF]MVVM模式的3种command 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL, ...
- WPF之MVVM模式讲解
WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI. 恰当的模式可以让我们轻松达到“高内聚 ...
- 【转】【WPF】MVVM模式的3种command
1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL,所以这3种模式中也有一些小差异,比如RelayCo ...
- WPF之MVVM模式(2)
我们都想追求完美 Every view in the app has an empty codebehind file, except for the standard boilerplate cod ...
- WPF之MVVM模式(1)
MVVM模式 一.MVVM模式概述 MVVM Pattern : Model\View\ViewModel View:视图.UI界面 ViewModel:ViewModel是对Model的封装,通过一 ...
- WPF中MVVM模式的 Event 处理
WPF的有些UI元素有Command属性可以直接实现绑定,如Button 但是很多Event的触发如何绑定到ViewModel中的Command呢? 答案就是使用EventTrigger可以实现. 继 ...
- WPF中 MVVM模式的Slider Binding.
对于Button的Command的绑定可以通过实现ICommand接口来进行,但是Slider并没有Command属性. 另外如果要实现MVVM模式的话,需要将一些Method和Slider的Even ...
- WPF采用MVVM模式(绑定:纯前台、命令:触发器绑定命令)
MVVM绑定 view-viewModel-model,模型介绍省略,就是创建类,添加字段封装属性.注:控件的绑定只能绑定到属性上,不能绑定到字段上: 接下来就是代码 (view): <Wind ...
- WPF中MVVM模式下控件自有的事件绑定
1.原因 在WPF中单纯的命令绑定往往不能满足覆盖所有的事件,例如ComboBox的SelectionChanged事件,DataGrid的SelectionChanged事件等等,这时就可以用事件绑 ...
随机推荐
- 在asp.net中使JQuery的Ajax用总结
自从有了JQuery,Ajax的使用变的越来越方便了,但是使用中还是会或多或少的出现一些让人短时间内痛苦的问题.本文暂时总结一些在使用JQuery Ajax中应该注意的问题,如有不恰当或者不完善的地方 ...
- HDU1423:Greatest Common Increasing Subsequence
浅谈\(DP\):https://www.cnblogs.com/AKMer/p/10437525.html 题目传送门:http://acm.hdu.edu.cn/showproblem.php?p ...
- Poj 2421 Constructing Roads(Prim 最小生成树)
题意:有几个村庄,要修最短的路,使得这几个村庄连通.但是现在已经有了几条路,求在已有路径上还要修至少多长的路. 分析:用Prim求最小生成树,将已有路径的长度置为0,由于0是最小的长度,所以一定会被P ...
- GWT嵌入纯HTML页面
众所周知,gwt页面是java代码所写,不存在html页面直接作用于gwt面板中.不过gwt也倒是提供了一些可用的功能,比如frame,这个是UI中的一个,内部可以设置URL,但是经过我测试后发现,这 ...
- java中try{}catch{}和finally{}的执行顺序问题
今天我给大家讲解一下java的的错误和异常处理机制以及相关异常的执行顺序问题.如有不足的地方,欢迎批评指正~ 1.首相简单介绍一下java中的错误(Error)和异常(Exception) 错误和异 ...
- Celery-4.1 用户指南: Concurrency (并发)
简介 Eventlet 的主页对它进行了描述:它是一个python的并发网络库,可以让你更改如何运行你的代码而不是怎么编写代码. 对高可扩展非阻塞IO操作,它使用 epoll或者libevent. C ...
- js防止重复点击
表单元素 disabled 没有之一. el.prop('disabled', true); ajax({}).done(function() { el.prop('disabled', false) ...
- Java 的基本语法
Java 语言严格区分大小写 一个 Java 源文件里可以定义多个类,但其中只能有一个类被定义为 public 类 如果源文件中包含了 public 类,源文件的名称必须和该 public 类同名 p ...
- 如何创建和配置Solaris10 zones (ZT)
http://thegeekdiary.com/how-to-create-and-configure-solaris-10-zones/ Solaris zones enables a softwa ...
- CSS——常用
1.超链接样式 a:link {color: #FF0000} /* 未访问的链接 */a:visited {color: #00FF00} /* 已访问的链接 */a:hover {color: ...