wpf MVVM模板的好例子

hujrc8aj  于 2023-11-20  发布在  其他
关注(0)|答案(9)|浏览(154)

我目前正在使用Microsoft MVVM模板,发现缺乏详细的示例令人沮丧。包含的ContactBook示例显示了很少的命令处理,我发现的唯一其他示例来自MSDN杂志文章,其中概念相似,但使用的方法略有不同,仍然缺乏任何复杂性。是否有任何像样的MVVM示例,至少显示了基本的CRUD操作和对话框/内容切换?
每个人的建议都非常有用,我将开始编制一个良好的资源列表

框架/模板

g2ieeal7

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中创建的类一样):

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

字符串

**Dialogs:**Dialogs和MVVM有点棘手。我更喜欢使用Mediator方法的对话框,你可以在这个StackOverflow问题中阅读更多关于它的信息:

WPF MVVM dialog example
我通常的方法,不是很经典的MVVM,可以总结如下:
一个对话框ViewModel的基类,它公开了提交和取消操作的命令,一个让视图知道对话框准备好关闭的事件,以及所有对话框中需要的其他东西。
对话框的通用视图--可以是一个窗口,也可以是一个自定义的“模态”覆盖类型控件。它的核心是一个内容呈现器,我们将视图模型转储到其中,它处理关闭窗口的连接--例如,在数据上下文更改时,您可以检查新的ViewModel是否从基类继承,如果是,订阅相关的close事件(处理程序将分配对话框结果)。如果您提供替代的通用关闭功能(例如X按钮),则应确保也在ViewModel上运行相关的close命令。
在某些地方,你需要为你的ViewModel提供数据模板,它们可以非常简单,特别是因为你可能有一个视图,每个对话框封装在一个单独的控件中。ViewModel的默认数据模板看起来像这样:

<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}">
   <views:AddressEditView DataContext="{Binding}" />
</DataTemplate>


对话框视图需要访问这些,因为否则它将不知道如何显示ViewModel,除了共享对话框UI之外,其内容基本上是这样的:

<ContentControl Content="{Binding}" />


隐式数据模板将视图Map到模型,但是谁启动它呢?
这是不那么mvvm的部分。一种方法是使用全局事件。我认为更好的方法是使用事件聚合器类型设置,通过依赖注入提供-这样事件对于容器是全局的,而不是整个应用程序。Prism使用Unity框架进行容器语义和依赖注入,总的来说我很喜欢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
}


对话框视图将绑定到位置数据,并将包含的ViewModel传递给内部ContentControl。ViewModel本身仍然不知道任何关于UI的信息。
一般来说,我不会使用ShowDialog()方法的DialogResult返回属性,也不会期望线程阻塞直到对话框关闭。非标准模式对话框并不总是这样工作,在复合环境中,你通常不希望事件处理程序像那样阻塞。我更喜欢让ViewModel来处理这个问题-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


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

tct7dpnv

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,它也解释了很多他的麦哲伦框架。

apeeds0o

apeeds0o3#

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

h6my8fg2

h6my8fg25#

我已经写了一个简单的MVVM例子从头开始的代码项目这里是链接MVVM WPF step by step。它从一个简单的3层架构开始,毕业你使用一些框架,如PRISM。


的数据

jc3wubiy

jc3wubiy6#

Cinch framework中的示例项目展示了基本的CRUD和导航工具。这是一个使用MVVM的相当好的示例,并包括一个multi-part article解释其用法和动机。

l7mqbcuq

l7mqbcuq7#

这里我添加了一个WPF(库存管理应用程序)应用程序的链接,该应用程序使用我设计的MVVM架构
它的UI很棒。https://github.com/shivam01990/InventoryManagement

8zzbczxx

8zzbczxx8#

我也分享了你的沮丧.我写的应用程序,我有这些3要求:

  • 可扩展
  • 带MVVM的WPF
  • GPL兼容示例

我发现的都是些零碎的东西,所以我就开始尽我所能地写。在我写了一点之后,我意识到可能还有其他人(像你一样)谁可以使用一个参考应用程序,所以我重构了通用的东西到一个WPF/MVVM应用程序框架,并在LGPL下发布。我命名为SoapBox Core。如果你去下载页面,您将看到它附带了一个小型演示应用程序,该演示应用程序的源代码也可以下载。

编辑:还发布了一个CodeProject article解释它是如何工作的。

mkh04yzy

mkh04yzy9#

甚至我也感到沮丧,直到我把这件事掌握在自己手中,我开始了IncEditor。
IncEditor(http://inceditor.codeplex.com)是一个试图向开发人员介绍WPF,MVVM和MEF的编辑器。我启动了它,并设法获得了一些功能,如“主题”支持。我不是WPF或MVVM或MEF的Maven,所以我不能在其中放置很多功能。

相关问题