Как вы объединили преимущества прямого подхода View-to-Model и MVVM в своих проектах WPF?

В нашем приложении есть много объектов Model, которые имеют сотни свойств.

Для каждого свойства в модели:

public string SubscriptionKind { get; set; }
...100x...

нам пришлось создать свойство с поддержкой INotifyPropertyChanged в ViewModel:

#region ViewModelProperty: SubscriptionKind
private int _subscriptionKind;
public int SubscriptionKind
{
    get
    {
        return _subscriptionKind;
    }

    set
    {
        _subscriptionKind = value;
        OnPropertyChanged("SubscriptionKind");
    }
}
#endregion

...100x...

Это означало, что когда наш View отправил событие Save, нам пришлось переназначить все эти значения модели представления обратно в модель:

customer.SubscriptionKind = this.SubscriptionKind
...100x...

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

Через некоторое время мы поняли, что было бы проще просто подключить DataContext представления напрямую к модели, что позволяет нам привязать элементы XAML непосредственно к свойствам объекта модели, чтобы событие сохранения просто сохранит объект без какого-либо сопоставления.

Что мы потеряли в ходе этого хода:

  • возможность через UpdateSourceTrigger=PropertyChanged выполнять детальную проверку и манипулировать в средствах настройки свойств ViewModel, что мне очень понравилось: этого у нас больше нет, поскольку любое изменение в XAML simple изменяет немое свойство модели

  • возможность (в будущем) создавать фиктивные представления, которые тестируют логику пользовательского интерфейса нашей модели представления новым способом, например «если для свойства SubscriptionKind установлено значение« Ежегодно », то (1) измените скидку на 10%, (2) запустите« анимацию поздравления »и (3) сделайте кнопку заказа более заметной.

Оба этих подхода имеют очевидные преимущества, например Первый подход «Просмотр прямо в модель», особенно в сочетании с LINQ-to-SQL, является прагматичным и позволяет быстро создавать полезное программное обеспечение, при условии, что вы используете {Binding...} вместо x:Name у вас все еще есть возможность «передать свои представления Blend Designer».

С другой стороны, хотя MVVM требует от вас утомительного сопоставления модели с ViewModel, он дает вам мощные преимущества проверки и тестирования, которых нет у первого подхода.

Как вам удалось объединить преимущества этих двух подходов в своих проектах?


person Edward Tanguay    schedule 22.10.2009    source источник
comment
Привет, у меня нет никаких конкретных советов, которые я могу вам дать, но когда я вижу MVVM, мне нужно подключить моего приятеля Кента. Я не знаю, применима ли какая-либо из его статей непосредственно к вашей проблеме, но вы можете увидеть кое-что, что поможет. Статьи по MVVM [kentb.blogspot.com/search/label/MVVM], если вы поискав Truss, вы даже найдете изящную структуру привязки Plain Old C # Object [Poco], которую он написал.   -  person johnny g    schedule 28.10.2009
comment
Интересно, решит ли Олсо такую ​​проблему?   -  person Jack Ukleja    schedule 17.11.2009


Ответы (4)


Поскольку ваша ViewModel имеет доступ к модели, вы также можете напрямую обернуть свойства модели:

#region ViewModelProperty: SubscriptionKindprivate
// int _subscriptionKind; - Use the model directly
public int SubscriptionKind
{
    get
    {
        return this.Model.SubscriptionKind;
    }
    set
    {
        if (this.Model.SubscriptionKind != value)
        {
            this.Model.SubscriptionKind = value;
            OnPropertyChanged("SubscriptionKind");
        }
    }
}
#endregion

Преимущество здесь в том, что вы можете сохранить свою валидацию в ViewModel, если хотите, и иметь больший контроль над тем, как она возвращается к вашей модели, но при этом меньше дублирования.

person Reed Copsey    schedule 22.10.2009

Почему бы не использовать инструмент сопоставления, такой как AutoMapper? Это быстро, и вам не нужно писать весь этот код сопоставления:

Mapper.CreateMap<MyModel, MyViewModel>();
MyViewModel vm = Mapper.Map(myModelInstance);

Действительно просто, и теперь вы получаете лучшее из обоих миров.

Automapper использует технику, которая генерирует сборки на лету для выполнения сопоставления. Это заставляет его выполняться так же быстро, как если бы вы написали весь этот утомительный код сопоставления, но вам не нужно.

person Anderson Imes    schedule 27.10.2009

Поскольку объекты моей модели являются бизнес-объектами, не связанными напрямую с моделью данных, я использую их непосредственно в ViewModel.

Первое сопоставление (модель данных с моделью бизнес-объекта) и создание свойств генерируются генератором кода.

person Eduardo Molteni    schedule 22.10.2009

Я использовал класс генератора t4 для создания своих ViewModels из XAML, не уверен, поможет ли это вашей ситуации.

person oddmike    schedule 18.11.2009