【问题标题】:ObservableCollection of generic ViewModel class通用 ViewModel 类的 ObservableCollection
【发布时间】:2011-05-11 13:23:25
【问题描述】:

我正在创建 MVVM 应用程序,在 Model 部分我有简单的基本抽象类 Animal 和类 Dog 从中派生出来的:

public abstract class Animal
{
    public int Age { get; set; }
}

public class Dog : Animal
{
    public string Name { get; set; }
}

ViewModel 部分包含 UI 友好的 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&lt;AnimalVM&gt;VM 类。问题是如何创建允许我存储不同类型的 Animal 的属性?我想实现这样的目标:

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&lt;AnimalVM&lt;Animal&gt;&gt; 属性更改为 ICollection 属性,然后使用一些字典 Animal -> AnimalVM 包装器创建 AnimalVM 列表和 Activator.CreateInstance() - 它可以工作,但是当我尝试扩展 AnimalListVM 时,添加另一个属性 SelectedAnimal 将在示例 View 中绑定到例如DataGrid 控件我对那种属性SelectedItem 的类型有另一个问题。它不能是 AnimalVM&lt;Animal&gt; 类型,因为当我的 Collection 中有 DogVM 对象时,它不适合这个并引发异常。

只要我有非泛型 AnimalVM,一切都会很清楚,但我不想在每个 DogVMCatVM,BirdVM 类派生自 AnimalVM。我怎样才能做到这一点?

【问题讨论】:

    标签: mvvm viewmodel generics observablecollection


    【解决方案1】:

    好的,我找到了一个解决方案,当然它非常简单:只需为您的泛型抽象基类创建另一个非泛型抽象基类,然后从新创建的非泛型类派生您的泛型类。在这种情况下,您还必须将属性从非泛型类重写为泛型类(更具体地说,覆盖它们),但您只需执行一次,因此您不必在每个泛型派生 ViewModel 中复制和粘贴相同的代码(在我们的每个 DogVM、CatVM、BirdVM 等示例中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2017-12-28
      • 2021-12-10
      • 1970-01-01
      • 2012-12-16
      • 2013-08-07
      相关资源
      最近更新 更多