我正在创建 MVVM 应用程序,在 Model 部分我有简单的基本抽象类 Animal 和类 Dog 源自它:
public abstract class Animal
{
public int Age { get; set; }
}
public class Dog : Animal
{
public string Name { get; set; }
}
ViewModel 部分包含对用户界面友好的 VM 类:
public abstract class AnimalVM<T> : ViewModelBase where T : Animal
{
protected readonly T animal;
public int Age
{
get { return animal.Age; }
set
{
animal.Age = value;
OnPropertyChanged("Age");
}
}
protected AnimalVM(T animal)
{
this.animal = animal;
}
}
public class DogVM : AnimalVM<Dog>
{
public string Name
{
get { return animal.Name; }
set
{
animal.Name = value;
OnPropertyChanged("Name");
}
}
public DogVM(Dog dog) : base(dog) { }
}
假设我有另一个包含ObservableCollection<AnimalVM>
的 VM 类。问题是如何创建那种允许我存储不同类型的动物的属性?我希望实现这样的目标:
public class AnimalListVM : ViewModelBase
{
// here is a problem, because AnimalVM<Animal> isn't compatible with DogVM
readonly ObservableCollection<AnimalVM<Animal>> animals;
public ObservableCollection<AnimalVM<Animal>> Animals
{
get { return animals; }
}
public AnimalListVM(IList<Animal> animals)
{
//this.animals = ...
}
}
我可以将ObservableCollection<AnimalVM<Animal>>
属性更改为ICollection
属性,然后使用某些词典 Animal - &gt;创建 AnimalVM 列表 AnimalVM 包装器和Activator.CreateInstance()
- 但是当我尝试扩展 AnimalListVM 时,添加另一个属性SelectedAnimal
,它将在示例中绑定到例如DataGrid控件我有另一个问题,那种属性SelectedItem
的类型。它不能是AnimalVM<Animal>
类型,因为当我的Collection中有 DogVM 对象时,它将不适合此并抛出异常。
如果我只有非通用的 AnimalVM ,那么一切都会很清楚,但我不想在每个 DogVM , CatVM <中复制和粘贴类似的属性/ em>, BirdVM 类派生自 AnimalVM 。我怎样才能做到这一点?
答案 0 :(得分:2)
好的,我找到了一个解决方案,当然它非常简单:只需为通用抽象基类创建另一个非泛型抽象基类,然后从新创建的非泛型类派生泛型类。在这种情况下,您还必须将属性从非泛型类重写为泛型类(更具体地覆盖它们),但是您只执行一次,因此您不必在每个通用派生的ViewModel中复制和粘贴相同的代码(在我们的示例中,每个DogVM,CatVM,BirdVM等)。