Как обновить вложенные ViewModels MVVM при изменении модели и наоборот? - PullRequest
5 голосов
/ 02 февраля 2011

Мне нужен совет, как решить проблему, которая нас сейчас беспокоит.

Допустим, у нас есть пара бизнес-объектов (POCO), таких как

public class UserGroup
{
    public virtual ICollection<Person> People { get; set; }
}

public class Person
{
    public virtual ICollection<Adress> Adresses { get; set; }
}

public class Adress
{
    public virtual string StreetName { get; set; }
}

Это немного упрощенно, но я надеюсь, что этого достаточно, чтобы вы поняли идею. UserGroup имеет коллекцию Person экземпляров, а каждый Person экземпляр имеет коллекцию Address instance.

ViewModelдля UserGroup POCO может выглядеть следующим образом:

public class UserGroupViewModel
{
    private UserGroup userGroupModel;

    public UserGroup UserGroupModel
    {
        get { return this.userGroupModel; }

        set
        {
            this.userGroupModel = value;

            this.PeopleViewModelCollection =
                 new ObservableCollection<PeopleViewModel>();

            foreach (Person p in this.UserGroupModel.People)
            {
                var personViewModel = new PersonViewModel();


                personViewModel.PersonModel = p;

                this.PeopleViewModelCollection.Add(personViewModel);
            }
        }
    }

    public ObservableCollection<PersonViewModel> PersonViewModelCollection
    {
        get;
        set;
    }
}

Где, как ViewModel для Person POCO, может выглядеть так:

public class PersonViewModel
{
    private Person personModel;

    public Person PersonModel
    {
        get { return this.personModel; }

        set
        {
            this.personModel = value;

            this.AddressViewModelCollection =
                 new ObservableCollection<AddressViewModel>();

            foreach (Address a in this.PersonModel.Adresses)
            {
                var addressViewModel = new AddressViewModel();


                addressViewModel.AddressModel = a;

                this.AdressViewModelCollection.Add(addressViewModel);
            }
        }
    }

    public ObservableCollection<AddressViewModel> AddressViewModelCollection
    {
        get;
        set;
    }
}

Опять же, это слишком упрощенно, но я хочу показать, что ViewModels имеют ObserableCollections других ViewModel, вложенных в них.

Установщик соответствующего свойства Model, например, PersonViewModel.PersonModel создает ViewModels для всехадреса Person и добавляет их к свойству ObservableCollection<AdressViewModels> AdressViewModelCollection PersonViewModel.

. На этом этапе мы могли бы использовать этот код для отображения этих моделей представления в представлении.Например, мы можем отобразить StreetName Person Adress.

Что теперь делать, если вы удалили Adress из Person?Удаление AdressViewModel из PersonViewModel.AdressViewModelCollection обновит графический интерфейс, но фактически не позволяет обновлять базовые модели.

Аналогично тому, как вы добавляете другую Adress в Person Модель существующейViewModels не будет отражать это изменение, поскольку PersonViewModel.AdressViewModelCollection будет перестроен только после повторного задания свойства PersonViewModel.PersonModel.

Существует ли (желательно простой) способ добиться этого двустороннего обновления междуViewModel и модель?Или, может быть, это не рекомендуется, и лучше решать эту проблему совершенно по-другому?

Мне очень хотелось бы услышать разные мнения по этой проблеме!

РЕДАКТИРОВАТЬ: Я хотел бы заявить, что наши классы моделей генерируются Entity Framework 4.0 и являются POCO (см. Пример бизнес-объектов выше).Я не уверен, было ли это достаточно ясно в самом вопросе.Мы хотели бы представить навигационные свойства (например, Person.Addresses) как ICollection<T>.

Ответы [ 2 ]

1 голос
/ 02 февраля 2011

Вы можете упростить вещи, используя динамические прокси (например, Castle.Proxy ), посмотрите на эту публикацию , чтобы узнать, как этого добиться.

0 голосов
/ 02 февраля 2011

Похоже, проблема не в каскадировании. Это синхронизация между моделью и моделью представления.

Вам нужно будет прослушать наблюдаемое событие коллекции коллекций, и здесь предоставляется реализация .

Я думаю, что ваш единственный вариант - реализовать INotifyPropertyChanged в вашей модели, так как структура сущностей не предоставляет способ обновить вашу ViewModel.

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