精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。
本文来源于TechNet,谢谢原作者。里面有我的翻译和理解,对于初学者和有一定经验的朋友都有提升能力作用,欢迎关注和收藏。
这篇文章链接到一个 TechNet 示例项目,您可以下载和浏览该项目。
它涵盖了 MVVM 的许多基本概念,以及一些常见的陷阱和解决方案。
我们的想法是下载示例,运行它以查看每个示例,然后通读此示例以及代码。当你完成时,你应该知道你需要知道的大部分内容 :)
下载: http://gallery.technet.microsoft.com/Easy-MVVM-Examples-48c94de3
如果你正在寻找更多好的 WPF 示例,您可能会喜欢 我的其他画廊示例项目 。我要问的是你给他们打分(星),谢谢。
注:实际上例子下载不到,想认真学习本文要点的找锐英源交流了。
MVVM 中最常见的第一个问题是如何从 ViewModel 调用 Window.Close() 等控件的方法。
这将在下一个示例中显示。
注:这个在我写的代码里用到了消息。
注:界面带参数,参数和属性绑定,这带来了灵活处理机制。
注:上面的代码就有点绕了,如果没有面向对象思维理解不了,分派器是ViewMode到View的关键,如果看不明白,请找锐英源软件。
一般 MVVM 使用的 依赖属性的主要缺点是它们需要在 UI 层上处理。
有关INPC 与 DP 辩论的更多信息,请阅读以下内容:
这个例子还展示了一个命令如何通过它的 CanExecute 委托来控制一个按钮是否被启用。
这再次远离控制器,更多地进入行为。
如果不满足条件,甚至无法触发该操作,并且当按钮被禁用时,用户很清楚这一点。
在此示例中,我们没有使用 command 参数,而是依靠 ViewModel 属性来填充所选项目。
如果没有,CanExecute方法返回false,这 会禁用按钮。
全部封装在命令中,代码干净整洁。
注:这个有意思,刚好开发里需要。
在此示例中,要关闭窗口,我们仍然使用 Window XAML 中的Attached Property,但该属性是 ViewModel 中的 Dependency Property。
简单使用如下:
WPF/MVVM 术语中的 POCO 类是不提供任何 PropertyChanged 事件的类。
这通常是遗留代码模块,或从 WinForms 转换而来。
下一个示例演示了当您不使用 PropertyChanged 事件时事情是如何开始中断的。
起初,一切似乎都很好。选中的项目全部更新,您可以更改现有人员的属性,并通过DataGrid添加新人员。
这些操作都是基于 UI 的操作,它们会更改TextBox.Text等 依赖属性,并自动触发PropertyChanged事件。但是,TextBox实际上应该显示一个 时间戳,由Dispatcher Timer后面的代码设置。
此外,单击按钮添加新人似乎不起作用,但确实有效。
如果您随后尝试在 DataGrid 中添加用户,则绑定会更新并显示先前添加的用户。 都有点琐碎。
作为替代方案,此 ViewModel 有一个自定义事件,用于表示关闭,在附加 ViewModel 时在后面的代码中处理。
以下窗口 与前面的 POCO 示例几乎相同。但是 TextProperty1 现在会 在其设置器中 触发 PropertyChanged 事件。
现在您会发现时间戳属性显示在 TextBox 上,如下所示。 但是,随着来自 INPC 界面的事件,其他 UI 绑定现在更加破碎。 (尝试示例项目)
如果您认为这是它所属的地方,那么关闭窗口的行为可以很高兴地保留在窗口中。
始终确保任何 ViewModel 具有上述预期事件的一种方法是让我们的 ViewModel(理想情况下在 ViewModelBase 中)继承 定义事件的接口。
然后,我们可以安全地将任何 ViewModel 转换回此接口,并将处理程序附加到预期事件。
注:vm和v之间的互动比较麻烦,这里给出的方法大家要记好。
从所有这些中学到的最重要的信息是,如果您可以将您使用的基(模型)类转换为 INPC 属性,请立即执行。您将为自己省去一个痛苦的世界,通过包装器进行不必要的数据编组,以及一大堆代码,这些代码可能会给您的实现带来错误和依赖关系。
但是,如果您有一个处理所有工作的业务对象,例如 现有的数据库模块或Web 服务客户端,该怎么办?
此示例显示了一个完整且几乎无代码的主/详细信息、CRUD 控制(用于数据库、Web 服务等) 通过主/子信息,我们的意思是有一个对象的主列表。然后选择一个列表项以在单独的框中获取项目详细信息。 CRUD是指创建、更新和 删除功能。您对集合或数据库中的对象执行的三件事。 通常,在大型应用程序中,我们会为编辑表单设计一个独立的用户控件,但这里有一个快速技巧来生成整个、完全连接的编辑表单,使用 ItemsTemplate的ItemsControl。
实际的编辑网格是一个 DataTemplate,而不是一个实际的控件。此 DataTemplate用作 ItemsControl的ItemTemplate:
绑定到所选人员的属性,只是 生成项目 的直接DataContext ——直接且简单。
注:组、取消和提交普通人用的少,是一些技巧。
要添加新用户,我们只需在 SelectedPerson 中创建一个新的“占位符”对象。
这显示并使用我们可以填写的新用户对象填充表单。
这就是我们将 ItemsControl ItemsSource 绑定到 SelectedPerson 而不是直接绑定到 DataGrid.SelectedItem 的原因。
如果新用户已删除/取消,我们只需将SeletedPerson设置回 null即可处理对象。
如果现有用户取消,我们在BindingGroup上 调用CancelEdit。
如果保存了新用户,我们在 业务对象上调用AddUser,然后触发 People集合上的PropertyChanged ,用于获取来自Business Object的新列表。
如果现有用户已保存,我们在 Business Object上调用UpdateUser并在BindingGroup上调用ComitEdit
如果现有用户已删除,我们 在 Business Object上调用DeleteUser ,然后在 People集合上触发PropertyChanged ,以获取来自Business Object的新列表。 例如,这里是我们为Save命令所做的:
注:MVVM的View也对数据库有整合能力,当然需要M配合,所以ItemsSource表示一个实体的能力,这个表示用在代码里,就让Model的数据更容易灵活使用。不好理解的话,先理解Combox的ItemSource。