WPF MVVM应用程序中具有继承的主详细信息关系



我认为这是一个相当基本的问题,但我还没有找到答案。

我有以下场景:在不使用任何形式的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类中的辅助方法,这取决于您。

最新更新