Привязка данных Silverlight к коллекции внутри коллекции

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

У меня есть класс, представляющий проект. Он содержит ObservableCollection<Layer> и каждый слой имеет ObservableCollection<Element>. Элемент - это абстрактный класс. Есть классы TextElement и ImageElement, унаследованные от Element.

Моя проблема в том, что пользовательский интерфейс никогда не обновляется, когда я меняю элемент внутри коллекции. Я использую INotifyPropertyChanged для всех своих свойств, и я ловлю CollectionChanged в коллекциях, но все равно не иду. Событие CollectionChanged для ObservableCollection<Element> никогда не происходит при обновлении одного из его элементов.

Это код, который у меня был изначально:

void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { this.NotifyChange("Elements"); }

Если кто может помочь, буду очень признателен.




Ответы (1)


ObservableCollection<> публикует CollectionChanged, когда элементы добавляются или удаляются, но НЕ делает этого, когда элемент внутри коллекции изменяется.

Чтобы обойти это, вы можете подписаться на событие CollectionChanged, а затем подписаться на INotifyPropertyChanged добавленных элементов внутри обработчика CollectionChanged:

elementCollection.CollectionChanged += (s, a) =>
{
    foreach (Element element in a.NewItems)
        element.PropertyChanged += ElementChanged;
};

Затем вы можете обновить пользовательский интерфейс с помощью метода ElementChanged.

person Eren Ersönmez    schedule 11.06.2012
comment
Спасибо за совет, но проблема в том, что событие elementCollection.CollectionChanged никогда не срабатывает. Свойства элементов обновляются, а Коллекция, содержащая элементы, - нет. - person Matthew; 11.06.2012
comment
CollectionChanged не срабатывает при изменении свойств элементов, но будет срабатывать при добавлении элементов в коллекцию. Таким образом, используя приведенный выше код, вы уже подписались на PropertyChanged элемента, когда он был добавлен в коллекцию, а позже, когда свойство этого элемента изменится, CollectionChanged не сработает, но PropertyChanged элемента сработает и ElementChanged будет запущен. - person Eren Ersönmez; 11.06.2012
comment
Я не уверен, что понимаю. Я реализовал приведенный выше код, но он запускается только тогда, когда я добавляю элемент. Есть ли способ обновить пользовательский интерфейс при изменении свойства, например. Element.Name? - person Matthew; 11.06.2012
comment
Что мне поместить в ElementChanged? - person Matthew; 12.06.2012
comment
вы можете попробовать поместить this.NotifyChange("Elements") в метод ElementChanged. - person Eren Ersönmez; 12.06.2012
comment
Да, это то, что я делал, но у меня это не работает. Я создал еще одно сообщение об этом с кодом здесь: stackoverflow.com/questions/10992832/ - person Matthew; 12.06.2012
comment
Ну, это НЕ то, что вы делали. У вас был this.NotifyChange("Elements"); внутри обработчика для CollectionChanged. Как я уже сказал, CollectionChanged не срабатывает при изменении элемента. В коде, который я рекомендовал выше, должен активироваться ElementChanged при изменении элемента. Таким образом, если вы поместите this.NotifyChange("Elements"); в ElementChanged, он должен выполнить то, что вы намеревались сделать в обработчике CollectionChanged. Вы действительно рекомендовали этот код? - person Eren Ersönmez; 12.06.2012
comment
Не могли бы вы показать мне, используя мой код, в другом посте, что вы имеете в виду? Я думал, что реализую ваш код, если вы посмотрите на мой класс Layer в другом посте. Спасибо за терпеливость. - person Matthew; 12.06.2012