ObservableCollection универсального класса ViewModel - PullRequest
2 голосов
/ 17 ноября 2010

Я создаю MVVM приложение и в разделе Модель у меня есть простой базовый абстрактный класс Животное и класс Собака , который получается изit:

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) { }
}

Предположим, у меня есть еще один VM класс, который содержит ObservableCollection<AnimalVM>.Проблема в том, как создать такое свойство, которое позволит мне хранить там различные типы 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<AnimalVM<Animal>> на свойство ICollection, а затем создать список AnimalVM , используя некоторый словарь Animal -> AnimalVM оболочка и Activator.CreateInstance() - это работает, но когда я пытаюсь расширить AnimalListVM , добавив еще одно свойство SelectedAnimal, которое будет связано в образце Вид Например, к элементу управления DataGrid у меня есть другая проблема с типом такого свойства SelectedItem.Он не может быть типа AnimalVM<Animal>, потому что, когда у меня есть объект DogVM в моей коллекции, он не подойдет для этого и не выдаст исключение.

Все будет ясно, если только яимел неуниверсальный AnimalVM , но я не хочу копировать и вставлять похожие свойства в каждый производный класс DogVM , CatVM , BirdVM от AnimalVM .Как мне этого добиться?

1 Ответ

2 голосов
/ 20 ноября 2010

Хорошо, я нашел решение, и, конечно, оно очень простое: просто создайте еще один неуниверсальный абстрактный базовый класс для вашего универсального абстрактного базового класса, а затем выведите свой универсальный класс из этого вновь созданного неуниверсального класса.В этом случае вы также должны переписать свойства из неуниверсального класса в универсальный класс (чтобы быть более точным переопределить их), но вы делаете это только один раз, поэтому вам не нужно копировать и вставлять один и тот же код в каждый производный универсальный ViewModel(в нашем примере в каждой DogVM, CatVM, BirdVM и т. д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...