Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
 MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
У меня пока только вариант, что и модель, и модель представления должны реализовать INotifyPropertyChanged. Далее, модель представления подписывается на событие PropertyChanged модели и перебирарет все её свойства. Найдя то, которое изменилось, оповещает об этом представление. Т. е. примерно так:

+
public class Model : INotifyPropertyChanged
{
    public int A { get; set; }
    public int B { get; set; }

    // Реализация INotifyPropertyChanged
    // ...
}

public class ViewModel : INotifyPropertyChanged
{
    Model _model;

    public int A { ... }
    public int B { ... }

    // Реализация INotifyPropertyChanged
    // ...

    public ViewModel()
    {
        _model.PropertyChanged += ModelPropertyChanged;
    }

    void ModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        // Вызываем метод OnPropertyChanged текущей ViewModel, 
        // оповещающий представление об изменении свойства _model
        // через изменение свойства текущей ViewModel.

        if (e.PropertyName == "A")
            OnPropertyChanged("A");
        else if (e.PropertyName == "B")
            OnPropertyChanged("B");
    }
}


Проблема в обработчике ModelPropertyChanged. Если свойст будет много, то это какой-то boilerplate. Может, есть способ лучше?
9 ноя 15, 07:28    [18387146]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Можно, конечно, завести по обычному событию для каждого свойства модели, и подписывать вью модель на каждое такое событие модели по отдельности. Толко это ещё бОльший boilerplate.
9 ноя 15, 07:29    [18387150]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Вообще, напрягает, что надо писать всю эту кучу вызовов OnPropertyChanged. Наверное, должен быть какой-то способ автоматизировать это? Автоматизировать задачу "оповестить вью об изменении модели".
9 ноя 15, 07:31    [18387152]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Если кто не понял, то в конструкции

if (e.PropertyName == "A")
            OnPropertyChanged("A");


первое "А" - это имя свойства модели, а второе "А" - имя свойства вью модели. Просто они совпадают. Надо было назвать по-разному, наверное, для понимания.
9 ноя 15, 07:34    [18387158]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Нет, иногда первый способ удобен. Например, когда свойство модели составное, а свойства вью модели - нет:

+
public class Model : INotifyPropertyChanged
{
    public int[] Numbers { get; set; }
}

public class ViewModel : INotifyPropertyChanged
{
    Model _model;

    public int Number1 { get { return _model.Numbers[0]; } }
    public int Number2 { get { return _model.Numbers[1]; } }

    void ModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Numbers")
        {
            OnPropertyChanged("Number1");
            OnPropertyChanged("Number2");
        }
    }
}


Но чаще возникает именно бойлерплейт из первого сообщения, поэтому хотелось бы знать способ его обойти.
9 ноя 15, 07:40    [18387166]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Да, может быть, кто-то знает, что мои поиски не нужны и будет лучшим подход именно в первом посте. Был бы рад, если бы кто-то объяснил, почему.
9 ноя 15, 07:46    [18387171]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21983
Создавай свойства зависимости. Это нормальная практика для ViewModel-и
9 ноя 15, 08:47    [18387229]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Shocker.Pro
Создавай свойства зависимости. Это нормальная практика для ViewModel-и

Не понял, а как они помогут при оповещении об изменении в модели?
9 ноя 15, 09:17    [18387308]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21983
Тебе не нужно об этом думать. Свойства зависимости реализуют нотификацию. Просто создаешь свойство зависимости вместо обычного свойства и привязываешь свойство представления к нему.
9 ноя 15, 10:07    [18387520]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21983
А, что касается самой модели... ну тут какая-то неверная архитектура, раз у тебя свойство модели транслируется в представление. ВьюМодель не должна зависеть от свойств модели, это модель должна хранить свои свойства, касающиеся отображения, во ВьюМодели, а не в себе.
9 ноя 15, 10:11    [18387534]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21983
VOva01101
модель представления подписывается на событие PropertyChanged модели
то есть вот это - неверно
9 ноя 15, 10:13    [18387543]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Shocker.Pro
А, что касается самой модели... ну тут какая-то неверная архитектура, раз у тебя свойство модели транслируется в представление. ВьюМодель не должна зависеть от свойств модели, это модель должна хранить свои свойства, касающиеся отображения, во ВьюМодели, а не в себе.

Идёт какой-то процесс в модели и пользователь должен информароваться о состоянии модели. Я почти нигде в интернете не встречал подобного, чтобы модель информировала вью (через вью модель или ещё как-то). Везде через INotifyPropertyChanged только модель изменяется в ответ на действия пользователя, но не наоборот - модель сама изменяет UI пользователя.

Свойства зависимости, вроде, относятся к WPF, а мне надо, чтобы модель был чистой, без примеси UI-библиотек. Ну, разве что в крайнем случае.

У меня в примерах, кстати, пропущено - надо ещё изменить свойство вью модели. Т. е. не так

if (e.PropertyName == "A")
    OnPropertyChanged("A");


а так

if (e.PropertyName == "A")
{
    A = _model.A;
    OnPropertyChanged("A"); // Это не нужно, если сеттер свойства А уже реализует оповещение.
}
9 ноя 15, 10:55    [18387761]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Смотрите классику https://msdn.microsoft.com/en-us/library/ff798384.aspx
Первый же ресунок - Model change events. Только вот в самой статье опять талдычат про оповещения между вью и вью моделью, а примера оповещения моделью вью модели и вью нет.
9 ноя 15, 10:57    [18387770]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Ну вот, собственно, то же советуют http://stackoverflow.com/a/15440949
Только когда будет много свойств у модели, которые надо обозревать - будет перебор всех этих свойств.

Либо будет куча событий в самой модели - на каждое свойство, которое надо обозревать. Тогда во вью модели надо только подписаться на всех них и перебора не будет.

Но чего-то мне кажется, что это какой-то оверхед. Проще нельзя?
9 ноя 15, 11:06    [18387833]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
А, ну, вобще, она и пишет, что всякие отправки сообщение между объектами есть и прочие. Ладно, почитаю... Похоже, что событие в модели, подписка на него во вью модели и последующая установка свойства вью модели - это самое простое.
9 ноя 15, 11:10    [18387865]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4036
INotifyPropertyChanged в модели? шта?

свойства сущности должны быть readonly (по возможности), если нужно изменить свойство, то создается новый объект.
вызов PropertyChanged может быть только во ViewModel
9 ноя 15, 13:56    [18389158]     Ответить | Цитировать Сообщить модератору
 Re: MVVM - Как оповестить представление об изменении модели?  [new]
VOva01101
Member

Откуда:
Сообщений: 34
Roman Mejtes
INotifyPropertyChanged в модели? шта?

свойства сущности должны быть readonly (по возможности), если нужно изменить свойство, то создается новый объект.
вызов PropertyChanged может быть только во ViewModel

Так я и вызываю PropertyChanged модели представления в модели представления. А PropertyChanged модели я ОТСЛЕЖИВАЮ в модели представления, а не вызываю.

Я в любом случае в модели представления могу следить за свойствами модиле - просто проверять их переодически, не изменились ли они. А раз так, то лучше создать событие изменения свойства модели и подписаться на него в модели представления.
9 ноя 15, 19:15    [18391507]     Ответить | Цитировать Сообщить модератору
Все форумы / WPF, Silverlight Ответить