Wpf MVVM模板的好例子

Wpf MVVM模板的好例子,wpf,mvvm,Wpf,Mvvm,我目前正在使用MicrosoftMVVM模板,发现缺少详细的示例令人沮丧。附带的ContactBook示例显示的命令处理非常少,我发现的另一个示例来自MSDN杂志的一篇文章,其中的概念相似,但使用的方法略有不同,仍然缺乏复杂性。是否有任何像样的MVVM示例至少显示了基本的CRUD操作和对话框/内容切换 每个人的建议都非常有用,我将开始编制一份优秀资源列表 框架/模板 有用的文章 屏幕广播 附加库 (对于导航更复杂的应用程序,我强烈建议使用此选项) 中

我目前正在使用MicrosoftMVVM模板,发现缺少详细的示例令人沮丧。附带的ContactBook示例显示的命令处理非常少,我发现的另一个示例来自MSDN杂志的一篇文章,其中的概念相似,但使用的方法略有不同,仍然缺乏复杂性。是否有任何像样的MVVM示例至少显示了基本的CRUD操作和对话框/内容切换


每个人的建议都非常有用,我将开始编制一份优秀资源列表

框架/模板

有用的文章

屏幕广播

附加库

  • (对于导航更复杂的应用程序,我强烈建议使用此选项)

中的示例项目显示了基本的CRUD和导航工具。这是一个使用MVVM的相当好的例子,其中包括一个解释其用法和动机的例子。

您看过吗?ContactManager示例中有很多好东西。通用WPF示例还提供了命令的良好概述。文档相当好,论坛也很活跃。推荐

我也分享了你的挫败感。我正在写一份申请,我有以下3个要求:

  • 可扩展
  • 带MVVM的WPF
  • GPL兼容示例
我只找到了一些零碎的东西,所以我就开始尽我所能写了。在我了解了一点之后,我意识到可能还有其他人(比如你)可以使用参考应用程序,所以我将通用的东西重构成WPF/MVVM应用程序框架,并在LGPL下发布了它。我给它取名。如果你转到下载页面,你会看到它附带了一个小的演示应用程序,该演示应用程序的源代码也可以下载。希望这对你有所帮助。另外,如果您想了解更多信息,请发电子邮件至scott{at}soapboxautomation.com


编辑:还发布了一条解释其工作原理的帖子。

不幸的是,没有一个伟大的MVVM示例应用程序可以做到所有事情,而且有很多不同的方法来做事情。首先,您可能希望熟悉其中一个应用程序框架(Prism是一个不错的选择),因为它们为您提供了方便的工具,如依赖注入、命令、事件聚合等,可以轻松尝试适合您的不同模式

棱镜版本:

它包括一个相当不错的示例应用程序(股票交易员),以及许多较小的示例和how to's。至少它很好地展示了人们用来使MVVM真正工作的几种常见子模式。我相信他们有CRUD和对话的例子

Prism并不一定适用于每个项目,但它是一件需要熟悉的好东西

积垢: 这一部分非常简单,WPF双向绑定使编辑大多数数据变得非常容易。真正的诀窍是提供一个可以轻松设置UI的模型。至少您希望确保您的ViewModel(或业务对象)实现
INotifyPropertyChanged
以支持绑定,并且您可以直接将属性绑定到UI控件,但您可能还希望实现
IDataErrorInfo
以进行验证。通常,如果您使用某种ORM解决方案,设置CRUD就是一个简单的过程

本文演示了简单的crud操作:

它是基于LinqToSql构建的,但这与示例无关-重要的是您的业务对象实现了
INotifyPropertyChanged
(由LinqToSql生成的类实现了这些功能)。MVVM不是该示例的重点,但我认为在这种情况下它并不重要

本文演示了数据验证

同样,大多数ORM解决方案生成的类已经实现了
IDataErrorInfo
,并且通常提供一种机制,使添加自定义验证规则变得容易

大多数情况下,您可以获取某个ORM创建的对象(模型),并将其包装到保存该对象的ViewModel和保存/删除命令中,这样就可以直接将UI绑定到模型的属性

视图看起来像这样(ViewModel有一个保存模型的属性
,类似于在ORM中创建的类):

对话框视图将绑定到位置数据,并将包含的ViewModel传递给内部
ContentControl
。ViewModel本身仍然对UI一无所知

通常,我不会使用
ShowDialog()
方法的
DialogResult
return属性,也不会期望线程在对话框关闭之前阻塞。非标准模式对话框并不总是这样工作,在复合环境中,您通常不希望事件处理程序以这种方式阻塞。我更喜欢让ViewModels处理这个问题——ViewModel的创建者可以订阅其相关事件、设置提交/取消方法等,因此不需要依赖此UI机制

因此,与此相反:

// in code behind
var result = somedialog.ShowDialog();
if (result == ...
我使用:

// 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

我更喜欢这种方式,因为我的大多数对话框都是非阻塞伪模态控件,这样做似乎比解决它更简单。易于单元测试。

Jason Dolinger充分利用了MVVM。就像伊戈尔提到的,没有一个好的例子。都结束了。大多数都是很好的MVVM示例,但在遇到复杂问题时就不是了。每个人都有自己的路。Laurent Bugnon也有一种在viewmodels之间进行通信的好方法。Cinch也是一个很好的例子。保罗·斯托维尔(Paul Stovel)也有一个很好的解释,那就是他的麦哲伦框架

甚至我也分享了
<ContentControl Content="{Binding}" />
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
}
// in code behind
var result = somedialog.ShowDialog();
if (result == ...
// 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