对话框的MVVM实现
来源:互联网 发布:记账小软件 编辑:程序博客网 时间:2024/05/20 19:46
如果你决定让你的应用程序应用MVVM模式的话,那么对话框的MVVM实现就会成为你要考虑的众多问题中的一个,因为基本上每一个应用程序都会有对话框,你的应用程序可能也不例外。
在用MVVM实现对话框的时候,我们主要会遇到两大问题:
1. ViewModel怎么关闭对话框,或者说怎么处理对话框的一些事件。
2. ViewModel中弹出对话框应该怎么处理 -- 弹出对话框会使UnitTest失败。
第一个问题: ViewModel怎么关闭对话框
假如你实现的对话框中有一个“确定”按钮,并且在ViewModel中有一个对应的命令绑定到这个按钮中,在这个按钮的命令处理函数中你需要关闭这个对话框。由于ViewModel并不知道对话框的存在,所以在ViewModel中是做不到直接关闭对话框的操作的。既然不能直接关闭,那就只能使用间接的方式来关闭对话框。下面介绍其中的一种方式:
定义一个接口:
public interface IDialogRequest
{
event EventHandler RequestClose;
}
让ViewModel实现这个接口,当需要关闭对话框的时候就触发这个事件。
那么谁来注册这个事件,以及在哪里注册?
你可能会直接在对话框的类中写这样的代码来注册RequestClose事件:
IDialogRequest dialogRequest = DataContext as IDialogRequest;
if(dialogRequest != null)
{
dialogRequest.RequestClose += ....;
}
这种方法很直接,但是并不是很理想,因为这样就意味着我们需要写Code-Behind代码了。
既然这样不是很好,那么该怎么办呢?我们可以使用Attached Property来解决这个问题,实现一个这样的类:
public class DialogRequstUtil
{
public static readonly DependencyProperty EnableDialogRequestProperty = Dependency.RegisterAttached(...);
...
//你可以在这个类是注册DialogRequest的事件
}
然后你就可以在XAML里面这样写:
<Window utils:DialogRequestUtil.EnableDialogRequest = "true" .../>
或者在代码中这样实现:
DialogRequestUtil.SetEnableDialogRequest(window, true);
这是目前使用的比较简单的解决方法。
第二个问题: ViewModel中弹出对话框应该怎么处理
经过Google,Bing,Baidu之后,找到了一种解决这个问题稍微比较好的方法--使用回调的方法,也就是我们在ViewModel中并不会直接去打开一个对话框,比如OpenFileDialog。而是调用一个回调函数,让这个回调函数去处理,这样就可以避免在UnitTest中弹出对话框,因为我们可以在UnitTest中实现另外一个不弹出对话框的回调函数。具体可以这么做:
public class TestViewModel
{
pubilc TestViewModel(Callback openFileDialogCallback)
{...}
private void OpenFileDialog()
{
openFileDialogCallback(...);
}
}
当我们在创建ViewModel的时候直接把回调函数传进来,这样做的目的就是可以让外部来控制是否要显示一个对话框。如果项目遇到这样的问题,不妨试一下这种方法。
优化代码
下面是打开一个对话框的场景,这样的代码也是很自然的:
MyDialog myDialog = new Dialog();
myDialow.Owner = MainWindow;
...
if(myDialog.ShowDialog() == true)
{
...
}
但是使用了MVVM之后,代码会变得复杂,也很不简洁,可能会变成这样:
MyDialogViewModel myDialogViewModel = new myDialogViewModel();
...
MyDialog myDialog = new Dialog()
myDialog.DataContext = myDialogViewModel;
myDialog.Owner = MainWindow;
if(myDialog.ShowDialog() == true)
{
...
}
你会发现我们不单单要初始化对话框,同时也需要初始化ViewModel。我们并不需要为所有的对话框都定义一个类,对话框里面的内容可以让ViewModel的数据模板来定义,我们可以实现代码:
MyDialogViewModel myDialogViewModel = new MyDialogViewModel();
...
if(DialogService.ShowDialog(myDialogViewMode, layoutResourceDictionary, MainWindow) == true)
{
...
}
这样的代码显得更加简洁自然,而且也不用去专门定义一个对话框类。所有对话框的显示和属性设置都由辅助类DialogService来实现。
- 对话框的MVVM实现
- WPF与MVVM的实现(一)MVVM简介
- 采用MVVM方式实现WPF的TreeView
- silverlight MVVM 附加属性AttachedBehaviors的实现
- 使用LocalBroadcast实现跨Activity的MVVM
- MVVM实现任意命令的绑定方法
- MVVM + ReactiveCocoa 一些简单功能的实现
- 实现一个类 Vue 的 MVVM 框架
- 230行实现一个简单的MVVM
- 浏览对话框的实现
- 实现对话框的伸缩
- 下载对话框的实现
- 弹出对话框的实现
- 定时对话框的实现
- alertDialog对话框的实现
- 动态对话框的实现
- 对话框的实现
- Android对话框的实现
- SerfJ REST框架的示例代码
- Linux内核里的延时API
- 蓝牙Profile的概念和常见种类
- 发发牢骚
- 深度与规模--MySpace和FaceBook模式比较
- 对话框的MVVM实现
- eclipse配置相关
- 定义C/C++全局变量/常量几种方法的区别
- 滑轮组原理
- 豆瓣找到自己的回复贴
- 网站开发人员应该知道的61件事
- Web Services 密钥库 jks文件的建立
- 用命令对sql进行备份
- ERP实施手记:生不如死的二次开发