ObservableCollection (int .NET 3.5), по-видимому, реализует событие PropertyChanged интересным способом .
protected event PropertyChangedEventHandler PropertyChanged;
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged;
Это означает, что защищенное PropertyChanged событие, скорее всего, предназначено только для внутренней реализации. Другое событие INotifyPropertyChanged.PropertyChanged - это событие, которое фактически выполняет реализацию интерфейса INotifyPropertyChanged как явный интерфейс . Странно, но я не вижу ни одного места в ObservableCollection, где фактически вызывается INotifyPropertyChanged.PropertyChanged . Это может указывать на то, что это ошибка в .NET 3.5, хотя я не проверял, например, вызывается ли событие измененного свойства для Count при добавлении элемента в коллекцию, но похоже, что он должен работать .
В реализации .NET 4.0 кажется, что событие INotifyPropertyChanged.PropertyChanged вместо этого подключается к тому же частному делегату, который используется защищенным событием PropertyChanged , которое могло быть исправлением ошибки. Также возможно, что это просто из-за различий в способах автоматической реализации событий в .NET 4.0 .
Исправление: Я убедился, что событие INotifyPropertyChanged.PropertyChanged вызвано ObservableCollection, поэтому предположения, которые я сделал выше на основе результатов использования Reflector для проверки реализации ObservableCollection, должны быть неточный. Я предполагаю, что отражатель делает странную ошибку, у меня пока нет доказательств этого.
Таким образом, чтобы ваш пример работал, вам нужно написать, чтобы этот пример работал, и выглядел бы как пример ниже, как это продемонстрировал Уилл в своем ответе.
SelectableList<int> intList = new SelectableList<int>();
((INotifyPropertyChanged)intList).PropertyChanged +=
new PropertyChangedEventHandler(intList_Changed);
Интересно, верно? Использование явных интерфейсов в основном используется, чтобы избежать неизбежных коллизий в элементах, необходимых для данного интерфейса, но они могут быть использованы в некотором смысле, чтобы скрыть существование элемента.
Если вы хотите вызвать события изменения свойств для своих собственных пользовательских свойств, которые вы вводите в своем подклассе, посмотрите на переопределение и / или вызов защищенного OnPropertyChanged метода, который также реализует ObservableCollection. Этот метод является хорошо принятым стандартом и позволяет подклассам вызывать события или обрабатывать события, не имея доступа к базовому делегату события. Обычно предпочитают использовать эту технику, кстати, вместо того, чтобы иметь обработчики событий ловушки подкласса к его собственным событиям базовых классов. Для большего количества примеров посмотрите, как события в различных элементах управления реализованы в WinForms и WPF.