没有派生的ViewModels但行为相同?

时间:2018-05-29 14:54:26

标签: c# wpf inheritance design-patterns mvvm

我正在编写一个小型的wpf桌面应用程序。我的BaseViewModel看起来像这样:

public abstract class BaseViewModel : INotifyPropertyChanged, IComparable<BaseViewModel>
{
    public abstract string GetDisplayText();
    public abstract string GetImageName();

    // INotifyPropertyChanged
}

我正在为mvvm寻找最佳的paxis。最多的说,一个模型有多个ViewModel,我同意它。

因为我希望所有相同类型的ViewModel以相同的方式处理 basics ,所以我认为它们应该相互派生。

public abstract class BaseCustomerVm : BaseViewModel
{
    public abstract string Name { get; set; }
    public abstract int Number { get; set; }
    public abstract bool IsPerson { get; set; }

    public override string GetDisplayText()
    {
        return Name;
    }

    public override string GetImageName()
    {
        if (IsPerson)
            return "Person";
        else
            return "Company";
    }
}

public class Customer1Vm : BaseCustomerVm
{
    public override string Name { get; set; }
    public override int Number { get; set; }
    public override bool IsPerson { get; set; }
}

为实现这一点,我有以下选择:

版本1:

public class Customer2Vm : BaseCustomerVm
{
    public override string Name { get; set; }
    public override int Number { get; set; }
    public override bool IsPerson { get; set; }
    // Further Properties
}

第2版:

public class Customer2Vm : Customer1Vm
{
    // Further Properties
}

在我的搜索中,我认为ViewModels不应该相互派生。这也是在this post中回答的。我的问题是:

  1. 为什么我不能这样做?
  2. 在没有继承的情况下处理sutch 基础的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

Customer2Vm应该来自Customer1Vm;我想你想要经典的继承问题:

  

Customer2Vm是否有&#34; is-a&#34;与Customer1Vm的关系?

只有你知道;但根据名字我会怀疑它。听起来我们应该从BaseCustomerVm推导出来。

至于你是否应该使用继承 ;我会说这里似乎很好。如果你想避免它(并且更喜欢组合),我建议让你的虚拟机实现一个ICustomerVm接口来获取属性;然后消费者将使用服务来获取显示文本和图像名称。我可能会坚持你拥有的东西(假设它或多或少正是你所展示的)。

答案 1 :(得分:0)

继承应该不是问题,直到您需要从多个(基本)视图模型继承,即如果您有几个不同的基本视图模型提供它们自己的公共基本功能。

由于您无法从C#中的多个类继承,因此您需要将常用功能分解为可以注入视图模型的可重用组件。

但是,你能够直接绑定到类中定义的一些公共属性的唯一方法是使用继承,从一系列不同的基本视图模型类继承没有任何问题。事实上,根据我的经验,这是一种非常常见的方法。视图中使用的大多数类型(ControlFrameworkElement等)都可以执行此操作。