我认为这是一个相当基本的问题,但我还没有找到答案。
我有以下场景:在不使用任何形式的EntityFrameWork的情况下,我有一个PersonViewModel和一个从PersonViewModel继承的PersonDetailsViewModel。在我的PersonView中,我在网格中显示了一组PersonViewModel。我有像Name、DateOfBirth等属性作为列。当我双击一个人时,会弹出一个与PersonDetailsViewModel绑定的PersonDetailView。在这个视图中显示了关于这个人的额外信息(性别、社会安全号码等)。我允许用户编辑所有属性。
现在,我想知道最好/常见的方法是确保PersonViewModel使用PersonDetailsViewModel中编辑的值进行更新。
我能想出几个选择。对于初学者来说,我可以选择不使用不同的ViewModel,而是使用PersonDetailViewModels在网格中显示,但这样做的缺点是,我需要为每个ViewModel检索大量不必要的数据。我还可以在PersonDetailsView关闭后同步相应的属性。我能想到的第三个选项是,我将在PersonDetailsView中包含一个类型为PersonView的属性,而不是从PersonView继承,并公开其属性,并将其用于PersonDetailsView中的绑定。PersonDetailsViewModel中的所有其他额外属性将在其构造函数中检索。
根据我的经验,更新共享相同数据的视图模型的最佳方法是使用Mediator模式发送数据已更新的通知消息。
为了有一个好的面向对象的设计,我们必须创建很多相互作用的类。如果某些原则如果没有应用,最终的框架将以一片混乱告终对象依赖于许多其他对象才能运行。为了避免紧密耦合的框架,我们需要一种机制来促进对象之间的交互,对象不知道其他物体的存在。
来源http://www.oodesign.com/mediator-pattern.html
通知说明发生了什么(数据已更新),而不是应该发生什么 通常,常见的MVVM库中都有Mediator实现。例如,Prism的EventAggregator
。
除了Sheridans的答案。我会将Detail公开为PersonDetailsViewModel 类型的属性
public class PersonViewModel
{
public PersonDetailsViewModel Detail {get;set;}
}
那么你的xaml看起来就像
<TextBlock Text="{Binding Detail.Gender}"/>
第1版:除了上面的评论
我不会做任何继承(这是用户1087702在他的问题中写的)。我只需要创建两个类:PersonVM和PersonVMDetail。如果请求是显示我的person对象的Details,那么我为什么不在PersonVM类中创建一个类型为PersonVMDetail的公共属性来填充这个请求呢?
实现需求的最简单方法是向PersonViewModel
类添加一个构造函数,该构造函数接受PersonDetailsViewModel
实例并更新其公共属性:
public PersonViewModel(PersonDetailsViewModel personDetailsViewModel)
{
Name = personDetailsViewModel.Name;
...
DateOfBirth = personDetailsViewModel.DateOfBirth;
}
PersonViewModel = new PersonViewModel(PersonDetailsViewModel);
当然,这不一定要在构造函数中。。。它可以很容易地成为PersonViewModel
类中的一个方法,甚至是一个单独的Factory Pattern类中的辅助方法,这取决于您。