Путаница по поводу INotifyPropertyChanged и обновления привязок - PullRequest
0 голосов
/ 07 июля 2010

Из того, что я (как мне кажется) понимаю, заключается в том, что реализация INotifyPropertyChanged в ModelView позволяет вызвать событие PropertyChanged в случае изменения свойства.

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

Правильно ли я понял теорию?

Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть инфраструктура DataGrid, связанная с ViewModel. Как только я изменяю значение Date, я вижу, как правильно установлено свойство ViewModel и возникает событие. Но я не подписался на это событие извне, как пользовательский интерфейс получает уведомление?

Я спрашиваю об этом, потому что я думаю, что пользовательский интерфейс вообще не является неофициальным. Я поместил второе текстовое поле, которое связывает ViewModel с тем же базовым свойством Model. Однако если я изменю это свойство с помощью DataGrid, TextBox (Mode = OneWay) не будет обновляться автоматически.

Я фактически использую работу MVVM-Light Frame и использую ViewModelBase вместо INotifyPropertyChanged и делаю RaisePropertyChanged (...). Но результат должен быть похожим.

Должен ли я как-то вручную подписать TextBox на это событие?

Редактировать: Я решил проблему, но не понимаю, почему именно это происходит. Прежде чем ответить на Вопрос, мне нужно немного подробнее рассказать об архитектуре. Сетка данных привязана к свойству A в ViewModelA, которое возвращает ObservableCollection<ViewModelB>. ViewModelB, на самом деле содержит все свойства, которые должна отображать Сетка. Все эти свойства запускаются в их Setters, естественно, OnProperyChanged.

TextBox был привязан к PropertyB, который также находится в ViewModelA. Но он возвращает непосредственно строку, поэтому базовый метод получения PerpertyB возвращает это:

_cashflowInputs[0].ProjectedDate.ToString();

Однако, если я не привязываю TextBox к этому свойству B, но привязываю его и к PropertyA, он работает:

Это странно. Я ожидал, что это сработает так же. Оба свойства находятся в одной и той же ViewModel и имеют одинаковый private ObservableCollection<ViewModelB>, почему это должно иметь значение?

public ObservableCollection<ViewModelB> PropertyA
        {
            get { return _cashflowInputs;}
        }

        public string PropertyB
        {
            get { return _cashflowInputs[0].ProjectedDate.ToString(); }
        }

Kave

Ответы [ 3 ]

2 голосов
/ 07 июля 2010

Вот краткий обзор того, как работает уведомление между объектом данных и элементом пользовательского интерфейса, когда объект данных реализует INotifyPropertyChanged.

1) Для изменения свойства вызывается установщик свойства объекта данных.

2) В установщике объект данных изменяет значение свойства и вызывает событие для уведомления любых элементов пользовательского интерфейса.привязанный к объекту данных свойство изменилось.Возникшее событие будет содержать имя только что измененного свойства.

3) Элемент пользовательского интерфейса обрабатывает событие и проверяет аргументы события, чтобы определить, какое свойство было изменено.

4) Теперь, когдаэлемент пользовательского интерфейса знает, какое свойство изменилось, он вызывает соответствующий метод получения, чтобы получить актуальное значение свойства, и обновляет себя с этим значением.

Итак, в вашем примере.Если свойство ProjectedDate обновлено, событие будет вызвано передачей имени свойства ProjectedDate элементу пользовательского интерфейса.Затем элемент пользовательского интерфейса вызовет метод получения свойства ProjectedDate, чтобы обновить себя.

Элемент пользовательского интерфейса не знает, что «PropertyB» изменилось, если событие никогда не вызывалось с именем свойства «PropertyB» в качестве аргумента.Таким образом, он не обновит себя новым значением, если он связан с 'PropertyB'.В какой-то момент событие должно быть вызвано с именем свойства «PropertyB» в качестве аргумента события для элемента пользовательского интерфейса, чтобы знать, что ему необходимо обновить себя с самым последним значением свойства.

0 голосов
/ 08 июля 2010

Привязка к PropertyB в элементе управления внутри шаблона данных в вашей DataGrid не будет работать, поскольку контекст данных элемента управления будет ViewModelB. Если вы хотите связать элемент внутри шаблона данных с чем-то вне контекста шаблона данных, вам нужно будет установить его контекст данных на что-то другое или использовать привязку данных от элемента к элементу, чтобы связать что-то вне вашего шаблона данных.

0 голосов
/ 07 июля 2010

Вы установили привязку к текстовому полю?

<TextBox Text="{Binding Path=PathToMyValue}"/>
...