Как я могу уведомить, что свойство предмета в наблюдаемой коллекции изменилось? - PullRequest
4 голосов
/ 07 июля 2011

Хорошо, у меня есть ItemsControl в файле XAML, который привязывается к ObservableCollection. ObservableCollection находится в классе модели представления (давайте назовем этот класс ViewModelA), и каждый элемент в ObservableCollection является экземпляром другого класса модели представления (давайте назовем класс ViewModelB).

В ViewModelA есть свойство, которое при изменении косвенно изменит значения свойств, найденных во многих экземплярах класса ViewModelB. Другими словами, он не идет прямо к ViewModelB и устанавливает его свойства, вызывая, таким образом, вызов INotifyPropertyChange, а скорее переходит к модели, устанавливает некоторые свойства в моей модели, и это изменение в моей модели влияет на то, что ViewModelB должен отображать вид.

Как я могу уведомить точку зрения, что что-то во ViewModelB изменилось?

Ответы [ 4 ]

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

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

Если ваша Модель реализует INotifyPropertyChanged, другой вариант будет иметь ваш класс ViewModelB, прослушивающий изменения в его обернутой модели, и генерирующий события измененных свойств по мере необходимости.

1 голос
/ 07 июля 2011

В идеале вы могли бы делать, как указано Ридом Копси ... Реализовать INotifyPropertyChanged на модели и заставить ViewModelB прослушивать эти события. Затем ViewModelB примет изменения независимо от того, где происходит обновление.

Однако, в некоторых случаях модель не (или не может) реализовать INotifyPropertyChanged. В этом случае вы можете рассмотреть возможность использования шаблона Event Aggregator для передачи сообщения между экземплярами ViewModelA и ViewModelB.

В этом случае вы можете опубликовать сообщение «модель изменена» из ViewModelA. Экземпляры ViewModelB подписались бы на это сообщение, и каждый из них получил бы уведомление, когда A опубликовал сообщение. Затем ViewModelB может вызвать соответствующие события PropertyChanged, чтобы сообщить пользовательскому интерфейсу, что изменилось.

Вы можете найти больше информации об Event Aggregator во многих платформах, включая

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

Если изменение в Моделях изменится в некоторых свойствах ViewModelB, и эти свойства имеют уведомление об изменении в пользовательском интерфейсе (то есть ViewModleB реализует INotifyPropertyChanged), изменение немедленно отобразится в пользовательском интерфейсе.

Итак, если у вас есть ObservableCollection другой viewmodelB, вам не нужно подключать события для свойства, измененного этой viewmodelB. Насколько я понимаю, кто бы ни изменял свойства viewmodelB (класс модели или кто-либо еще), и если свойства имеют уведомление об изменении, представление обновится автоматически.

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

Для решения этой проблемы я создал класс VeryObservableCollection.Для каждого добавляемого объекта он подключает событие NotifyPropertyChanged объекта к обработчику, который запускает событие CollectionChanged.Для каждого удаленного объекта он удаляет обработчик.Очень просто и даст вам именно то, что вы хотите.Неполный код:

public class VeryObservableCollection<T> : ObservableCollection<T>

/// <summary>
/// Override for setting item
/// </summary>
/// <param name="index">Index</param>
/// <param name="item">Item</param>
protected override void SetItem(int index, T item)
{
    try
    {
        INotifyPropertyChanged propOld = Items[index] as INotifyPropertyChanged;
        if (propOld != null)
            propOld.PropertyChanged -= new PropertyChangedEventHandler(Affecting_PropertyChanged);
    }
    catch (Exception ex)
    {
        Exception ex2 = ex.InnerException;
    }
    INotifyPropertyChanged propNew = item as INotifyPropertyChanged;
    if (propNew != null)
        propNew.PropertyChanged += new PropertyChangedEventHandler(Affecting_PropertyChanged);

    base.SetItem(index, item);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...