我目前正在使用Microsoft MVVM模板,并发现缺乏详细的示例令人沮丧.包含的ContactBook示例显示了非常少的命令处理,我发现的唯一其他示例来自MSDN杂志文章,其中概念类似但使用稍微不同的方法,但仍然缺乏任何复杂性.是否有任何体面的MVVM示例至少显示基本的CRUD操作和对话/内容切换?
每个人的建议都非常有用,我将开始编制一份好的资源清单
框架/模板
有用的文章
截屏
其他图书馆
Ego*_*gor 58
不幸的是,没有一个伟大的MVVM示例应用程序可以完成所有工作,并且有很多不同的方法可以做.首先,您可能希望熟悉其中一个应用程序框架(Prism是一个不错的选择),因为它们为您提供了依赖注入,命令,事件聚合等方便的工具,以便轻松尝试适合您的不同模式.
棱镜版本:http:
//www.codeplex.com/CompositeWPF
它包括一个相当不错的示例应用程序(股票交易员)以及许多较小的示例和如何做.至少它很好地演示了人们用来使MVVM实际工作的几种常见子模式.我相信他们有CRUD和对话的例子.
Prism不一定适用于每个项目,但熟悉它是一件好事.
CRUD:
这部分很简单,WPF双向绑定使编辑大多数数据变得非常容易.真正的诀窍是提供一个可以轻松设置UI的模型.至少,您希望确保ViewModel(或业务对象)实现INotifyPropertyChanged以支持绑定,并且您可以将属性直接绑定到UI控件,但您可能还希望实现IDataErrorInfo验证.通常,如果您使用某种ORM解决方案设置CRUD是一个快照.
本文演示了简单的crud操作:http: //dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
它建立在LinqToSql之上,但这与示例无关 - 所有重要的是您的业务对象实现INotifyPropertyChanged(由LinqToSql生成的类).MVVM不是那个例子的重点,但我认为在这种情况下并不重要.
本文演示数据验证
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
同样,大多数ORM解决方案生成已经实现的类,IDataErrorInfo并且通常提供一种机制,以便于添加自定义验证规则.
大多数情况下,您可以获取由某些ORM创建的对象(模型)并将其包装在保存它的ViewModel和用于保存/删除的命令中 - 并且您已准备好将UI直接绑定到模型的属性.
视图看起来像这样(ViewModel有一个Item包含模型的属性,就像在ORM中创建的类一样):
<StackPanel>
<StackPanel DataContext=Item>
<TextBox Text="{Binding FirstName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
<TextBox Text="{Binding LastName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
</StackPanel>
<Button Command="{Binding SaveCommand}" />
<Button Command="{Binding CancelCommand}" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
对话框:
对话框和MVVM有点棘手.我更喜欢使用Mediator方法的对话框,你可以在这个StackOverflow问题中阅读更多关于它的内容:
WPF MVVM对话框示例
我常用的方法,不是很经典的MVVM,可归纳如下:
对象ViewModel的基类,用于公开提交和取消操作的命令,一个事件,让视图知道对话框已准备好关闭,以及您在所有对话框中需要的任何其他内容.
对话框的通用视图 - 可以是窗口,也可以是自定义"模态"叠加类型控件.它的核心是我们将视图模型转储到的内容呈现器,它处理关闭窗口的连接 - 例如,在数据上下文更改时,您可以检查新的ViewModel是否从您的基类继承,如果是,订阅相关的关闭事件(处理程序将分配对话框结果).如果您提供备用通用关闭功能(例如,X按钮),则还应确保在ViewModel上运行相关的关闭命令.
在某些地方,您需要为ViewModel提供数据模板,它们可以非常简单,尤其是因为您可能拥有封装在单独控件中的每个对话框的视图.ViewModel的默认数据模板将如下所示:
<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}">
<views:AddressEditView DataContext="{Binding}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
对话框视图需要有权访问这些,因为否则它将不知道如何显示ViewModel,除了共享对话框UI之外,其内容基本上是这样的:
<ContentControl Content="{Binding}" />
Run Code Online (Sandbox Code Playgroud)
隐式数据模板会将视图映射到模型,但谁启动它?
这是不那么mvvm的部分.一种方法是使用全局事件.我认为更好的做法是使用通过依赖注入提供的事件聚合器类型设置 - 这样事件对于容器而不是整个应用程序是全局的.Prism使用统一框架进行容器语义和依赖注入,总体来说我非常喜欢Unity.
通常,根窗口订阅此事件是有意义的 - 它可以打开对话框并将其数据上下文设置为通过引发事件传入的ViewModel.
通过这种方式进行设置,ViewModels可以让应用程序打开一个对话框并在不知道任何UI知识的情况下响应用户操作,因此大部分MVVM都保持完整.
然而,有时候UI必须引发对话框,这会使事情变得有点棘手.例如,考虑对话位置是否取决于打开它的按钮的位置.在这种情况下,当您请求打开对话框时,您需要具有一些UI特定信息.我通常创建一个单独的类来保存ViewModel和一些相关的UI信息.不幸的是,有些耦合似乎不可避免.
按钮处理程序的伪代码,用于引发需要元素位置数据的对话框:
ButtonClickHandler(sender, args){
var vm = DataContext as ISomeDialogProvider; // check for null
var ui_vm = new ViewModelContainer();
// assign margin, width, or anything else that your custom dialog might require
...
ui_vm.ViewModel = vm.SomeDialogViewModel; // or .GetSomeDialogViewModel()
// raise the dialog show event
}
Run Code Online (Sandbox Code Playgroud)
对话框视图将绑定到位置数据,并将包含的ViewModel传递给内部ContentControl.ViewModel本身仍然不了解UI.
一般情况下,我不使用方法的DialogResult返回属性ShowDialog()或期望线程在对话框关闭之前阻塞.非标准模式对话框并不总是这样,在复合环境中,您通常不希望事件处理程序无论如何都要阻塞.我更喜欢让ViewModel处理这个问题 - ViewModel的创建者可以订阅它的相关事件,设置提交/取消方法等,所以不需要依赖这个UI机制.
而不是这个流程:
// in code behind
var result = somedialog.ShowDialog();
if (result == ...
Run Code Online (Sandbox Code Playgroud)
我用:
// in view model
var vm = new SomeDialogViewModel(); // child view model
vm.CommitAction = delegate { this.DoSomething(vm); } // what happens on commit
vm.CancelAction = delegate { this.DoNothing(vm); } // what happens on cancel/close (optional)
// raise dialog request event on the container
Run Code Online (Sandbox Code Playgroud)
我更喜欢这种方式,因为我的大多数对话框都是非阻塞的伪模态控件,这种做法似乎比解决它更直接.易于单元测试.
Jason Dolinger 对MVVM 做了一个很好的截屏视频.像叶戈尔提到的那样,没有一个很好的例子.他们都结束了.大多数都是很好的MVVM示例,但是当您遇到复杂问题时则不行.每个人都有自己的方式.Laurent Bugnion也有很好的方式在视图模型之间进行通信. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch也是一个很好的例子.Paul Stovel有一个很好的帖子,他的Magellan框架也解释了很多.
| 归档时间: |
|
| 查看次数: |
61439 次 |
| 最近记录: |