我的问题是:如何管理视图模型的继承链?
我的情况:
我有一个标准的 ViewModelBase ,它只实现了INotifyPropertyChanged接口。
此外,我有一个 BusinessObjectViewModel ,它有一个Guid,一个 PersonBaseViewModel ,其中包含人员核心数据,一个 CustomerViewModel ,其中包含与客户相关的内容和一个 EmployeeViewModel 与员工相关的东西。
所有viewmodel肯定都封装了一个modelobject(Customer,Employee,PersonBase)。
模型通过构造函数进入viewmodel。
如果我使用构造函数链(每个viewmodel调用基础构造函数),每个viewmodel都有它的模型来从模型返回封装的值。
但是我必须在每个viewmodel中都有一个Model属性。在CustomerViewModel的情况下,我将在 CustomerViewModel 中引用一个引用,一个在PersonBaseViewModel中,一个在 BusinessObjectViewModel 中引用同一个对象。这听起来很愚蠢。
或者我必须在上部视图模型中转换每个属性访问。
P.S。这只是我模型层次结构的一小部分。
提前致谢。
答案 0 :(得分:2)
最简单的答案IMO是使用Generics,这可能就像
一样简单public abstract class ViewModelBase<TModel> TModel : class{
public TModel Model { get; protected set; }
}
.net输入系统会知道你的TModel是一个人,客户或其他没有铸造的东西。
如果您需要更多内容,或者您想发布一些需要帮助的代码,请告诉我们。是的,一开始就让你的超类型heirarchies恰到好处。
HTH,
Berryl
答案 1 :(得分:1)
如果BusinessObject和Person类(及其VM对应物)是抽象的,那么您可以像这样访问正确的模型:
public abstract class BusinessObjectViewModel : ViewModelBase
{
protected abstract BusinessObject BusinessObject { get; }
protected BusinessObject Model { get { return this.BusinessObject; } }
}
public abstract class PersonViewModel : BusinessObjectViewModel
{
protected abstract Person Person { get; }
protected new Person Model { get { return this.Person; } }
protected override sealed BusinessObject BusinessObject
{
get { return this.Model; }
}
}
public class CustomerViewModel : PersonViewModel
{
protected new Customer Model { get; set; }
protected override sealed Person Person
{
get { return this.Model; }
}
}
public class EmployeeViewModel : PersonViewModel
{
protected new Employee Model { get; set; }
protected override sealed Person Person
{
get { return this.Model; }
}
}
这样,每个派生的VM类通过实现抽象属性为其基本VM Model属性提供值,并隐藏基类Model属性,因此每个VM都使用适当类型的Model属性(因此不需要强制转换)。 / p>
这种方法有其优点和缺点:
优点:
缺点:
另一种方法是:
public class BusinessObjectViewModel : ViewModelBase
{
protected BusinessObject Model { get; private set; }
public BusinessObjectViewModel(BusinessObject model)
{
this.Model = model;
}
}
public class PersonViewModel : BusinessObjectViewModel
{
protected new Person Model { get { return (Person)base.Model; } }
public PersonViewModel(Person model)
: base(model)
{
}
}
public class CustomerViewModel : PersonViewModel
{
protected new Customer Model { get { return (Customer)base.Model; } }
public CustomerViewModel(Customer model)
: base(model)
{
}
}
public class EmployeeViewModel : PersonViewModel
{
protected new Employee Model { get { return (Employee)base.Model; } }
public EmployeeViewModel(Employee model)
: base(model)
{
}
}
优点:
缺点:
基于这种分析,我会选择第二种选择,因为修复它唯一的缺点,即铸造性能,将是不必要的微优化,这在WPF环境中是不可察觉的。
答案 2 :(得分:0)
如果您只想在ViewModel中公开Model属性,则无需在ViewModel中重新声明Model属性以公开它们。我通常将底层的Model对象作为ViewModel中的属性公开。在您的情况下,例如在您的EmployeeViewModel中,您将拥有:
private Employee _MyEmployee;
public Employee MyEmployee {
get
{
return _MyEmployee;
}
set
{
_MyEmployee = value;
NotifyPropertyChanged(x=>x.MyEmployee);
}
然后,您的View可以通过ViewModel中公开的MyEmployee属性绑定到您的Employee属性。据我所知,当您想要在VM中重新声明或包装模型属性时,唯一的情况是您需要进行一些数据操作才能呈现给您的视图。