我目前正在使用Microsoft MVVM模板,发现缺乏详细的示例令人沮丧。包含的ContactBook示例显示了很少的命令处理,我发现的唯一其他示例来自MSDN杂志文章,其中概念相似,但使用的方法略有不同,仍然缺乏任何复杂性。是否有任何像样的MVVM示例,至少显示了基本的CRUD操作和对话框/内容切换?
每个人的建议都非常有用,我将开始编制一个良好的资源列表
框架/模板
- WPF Model-View-ViewModel Toolkit
- MVVM Light Toolkit的
- Prism的
- Caliburn的
- Cinch的
有用的文章 - WPF Apps With The Model-View-ViewModel Design Pattern的
- Data Validation in .NET 3.5
- Using a ViewModel to Provide Meaningful Validation Error Messages
- Action based ViewModel and Model validation
- Dialogs
- Command Bindings in MVVM
- More than just MVC for WPF
- MVVM + Mediator Example Application
屏幕截图 - Jason Dolinger on Model-View-ViewModel
其他图书馆 - WPF Disciples' improved Mediator Pattern implementation(我强烈建议对于具有更复杂导航的应用程序使用此方法)
- MVVM Light Toolkit Messenger
9条答案
按热度按时间g2ieeal71#
不幸的是,没有一个伟大的MVVM示例应用程序可以做所有的事情,并且有很多不同的方法来做事情。首先,您可能想熟悉其中一个应用程序框架(Prism是一个不错的选择),因为它们为您提供了方便的工具,如依赖注入,命令,事件聚合等,可以轻松尝试适合您的不同模式。
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生成的类实现了INotifyPropertyChanged
)。MVVM不是该示例的重点,但我认为它在本例中并不重要。本文演示了数据验证
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx的
同样,大多数ORM解决方案生成的类已经实现了
IDataErrorInfo
,并且通常提供了一种机制,可以轻松地添加自定义验证规则。大多数情况下,您可以将某个ORM创建的对象(模型) Package 在一个ViewModel中,ViewModel保存该对象和保存/删除命令--然后您就可以直接将UI绑定到模型的属性上。
视图看起来像这样(ViewModel有一个属性
Item
来保存模型,就像在ORM中创建的类一样):字符串
**Dialogs:**Dialogs和MVVM有点棘手。我更喜欢使用Mediator方法的对话框,你可以在这个StackOverflow问题中阅读更多关于它的信息:
WPF MVVM dialog example的
我通常的方法,不是很经典的MVVM,可以总结如下:
一个对话框ViewModel的基类,它公开了提交和取消操作的命令,一个让视图知道对话框准备好关闭的事件,以及所有对话框中需要的其他东西。
对话框的通用视图--可以是一个窗口,也可以是一个自定义的“模态”覆盖类型控件。它的核心是一个内容呈现器,我们将视图模型转储到其中,它处理关闭窗口的连接--例如,在数据上下文更改时,您可以检查新的ViewModel是否从基类继承,如果是,订阅相关的close事件(处理程序将分配对话框结果)。如果您提供替代的通用关闭功能(例如X按钮),则应确保也在ViewModel上运行相关的close命令。
在某些地方,你需要为你的ViewModel提供数据模板,它们可以非常简单,特别是因为你可能有一个视图,每个对话框封装在一个单独的控件中。ViewModel的默认数据模板看起来像这样:
型
对话框视图需要访问这些,因为否则它将不知道如何显示ViewModel,除了共享对话框UI之外,其内容基本上是这样的:
型
隐式数据模板将视图Map到模型,但是谁启动它呢?
这是不那么mvvm的部分。一种方法是使用全局事件。我认为更好的方法是使用事件聚合器类型设置,通过依赖注入提供-这样事件对于容器是全局的,而不是整个应用程序。Prism使用Unity框架进行容器语义和依赖注入,总的来说我很喜欢Unity。
通常,根窗口订阅此事件是有意义的-它可以打开对话框并将其数据上下文设置为通过引发的事件传入的ViewModel。
通过这种方式设置,ViewModels可以让应用程序打开一个对话框并响应用户操作,而无需了解UI的任何信息,因此在大多数情况下MVVM保持完整。
然而,有时候UI必须提升对话框,这会使事情变得有点棘手。例如,考虑一下,如果对话框的位置取决于打开它的按钮的位置。在这种情况下,当你请求打开对话框时,你需要一些UI特定的信息。我通常创建一个单独的类来保存ViewModel和一些相关的UI信息。不幸的是,一些耦合似乎是不可避免的。
按钮处理程序的伪代码,它引发一个需要元素位置数据的对话框:
型
对话框视图将绑定到位置数据,并将包含的ViewModel传递给内部
ContentControl
。ViewModel本身仍然不知道任何关于UI的信息。一般来说,我不会使用
ShowDialog()
方法的DialogResult
返回属性,也不会期望线程阻塞直到对话框关闭。非标准模式对话框并不总是这样工作,在复合环境中,你通常不希望事件处理程序像那样阻塞。我更喜欢让ViewModel来处理这个问题-ViewModel的创建者可以订阅其相关事件,设置提交/取消方法等,因此无需依赖此UI机制。因此,与此流程相反:
型
我用途:
型
我更喜欢这种方式,因为我的大多数对话框都是非阻塞的伪模态控件,这样做似乎比绕过它更简单。
tct7dpnv2#
Jason Dolinger做了一个很好的MVVM screencast。就像Egor提到的,没有一个好的例子。他们都结束了。大多数都是很好的MVVM例子,但是当你遇到复杂的问题时就不是了。每个人都有自己的方式。Laurent Bugnion也有一个很好的方式来在视图模型之间进行通信。http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch也是一个很好的例子。Paul Stovel有一个很好的post,它也解释了很多他的麦哲伦框架。
apeeds0o3#
你看过Caliburn吗?ContactManager示例中有很多好东西。通用WPF示例也提供了命令的良好概述。文档相当不错,论坛也很活跃。推荐!
5us2dqdw4#
发现这一个有用。也有代码。
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
h6my8fg25#
我已经写了一个简单的MVVM例子从头开始的代码项目这里是链接MVVM WPF step by step。它从一个简单的3层架构开始,毕业你使用一些框架,如PRISM。
的数据
jc3wubiy6#
Cinch framework中的示例项目展示了基本的CRUD和导航工具。这是一个使用MVVM的相当好的示例,并包括一个multi-part article解释其用法和动机。
l7mqbcuq7#
这里我添加了一个WPF(库存管理应用程序)应用程序的链接,该应用程序使用我设计的MVVM架构。
它的UI很棒。https://github.com/shivam01990/InventoryManagement
8zzbczxx8#
我也分享了你的沮丧.我写的应用程序,我有这些3要求:
我发现的都是些零碎的东西,所以我就开始尽我所能地写。在我写了一点之后,我意识到可能还有其他人(像你一样)谁可以使用一个参考应用程序,所以我重构了通用的东西到一个WPF/MVVM应用程序框架,并在LGPL下发布。我命名为SoapBox Core。如果你去下载页面,您将看到它附带了一个小型演示应用程序,该演示应用程序的源代码也可以下载。
编辑:还发布了一个CodeProject article解释它是如何工作的。
mkh04yzy9#
甚至我也感到沮丧,直到我把这件事掌握在自己手中,我开始了IncEditor。
IncEditor(http://inceditor.codeplex.com)是一个试图向开发人员介绍WPF,MVVM和MEF的编辑器。我启动了它,并设法获得了一些功能,如“主题”支持。我不是WPF或MVVM或MEF的Maven,所以我不能在其中放置很多功能。