Страницы

Поиск по вопросам

среда, 24 октября 2018 г.

Как работает интерфейс INotifyPropertyChanged?

Собственно сабж: как изнутри работает данный интерфейс? Что происходит при вызове метода NotifyPropertyChanged(string propertyName)? Как UI элемент узнает, что что-то произошло и нужно "перерисоваться"? Объясните пожалуйста. Чем подробнее - тем лучше)


Ответ

Если вы имплементируете интерфейс INotifyPropertyChanged, то вы должны определить event PropertyChanged, и отправлять его каждый раз, когда значение изменится.
Если у вас есть привязка к какому-то свойству, то Binding в числе прочего проверяет, реализует ли binding source (то есть, объект, к свойству которого происходит binding), этот интерфейс, и если да, то подписывается на этот самый event. По приходу event'а значение свойства перечитывается (через reflection).

Дополнение: А что происходит с ItemsSource? А для него интересен интерфейс INotifyCollectionChanged, который сообщает о том, что в коллекции появились/исчезли элементы.
Если вы привязываете ItemsSource в ListView к коллекции, Binding заботится о том, чтобы ListView знал текущее значение самой коллекции. То есть, если вы коллекцию подмените на другую коллекцию, об этом сообщит Binding. А вот нотификация об изменении списка элементов коллекции происходит следующим образом.
Когда ListView видит, что объект коллекции поменялся (эту информацию поставляет Binding), он самостоятельно проверяет наличие интерфейса INotifyCollectionChanged, и если коллекция его поддерживает, подписывается на событие CollectionChanged. Когда это событие приходит, в нём есть NotifyCollectionChangedEventArgs, который содержит информацию о том, что именно произошло, какие элементы добавились (и куда), а какие исчезли (и откуда). Имея эту информацию, ListView может перестроить список.
Заметьте, что обыкновенный List не реализует интерфейс INotifyCollectionChanged, поэтому если в привязке лежит List, ListView автоматически обновляться не будет. Обычно никто не реализует INotifyCollectionChanged самостоятельно, а пользуются готовыми коллекциями. Например, ObservableCollection

Комментариев нет:

Отправить комментарий