Отказ от подписки на событие CollectionChanged коллекции, хранящейся во вложенном свойстве - PullRequest
1 голос
/ 02 декабря 2011

Хорошо, поэтому у меня есть прикрепленное свойство (объявленное в статическом классе), которое присоединяет свойство INotifyCollectionChanged к объекту.

Когда свойство установлено, я хочу начать мониторинг коллекции на предмет измененийи затем выполните какое-либо действие на объекте, к которому присоединена коллекция .

Первая попытка:

private static void MyProperty_OnChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
{
    // We need both the dependency object, and the collection args to process the notification
    NotifyCollectionChangedEventHandler changedFunc = (sender, eventArgs) => MyProperty_OnCollectionChanged( d, sender, eventArgs );

    if( e.OldValue != null )
        e.OldValue.CollectionChanged -= changedFunc;   // Can you see the bug?
    if( e.NewValue != null )
        e.NewValue.CollectionChanged += changedFunc;

}

Чтобы получить объект, коллекция присоединенав обработчик, я тяну d в закрытие.Достаточно просто, верно?

Ну, я уверен, что вы можете увидеть ошибку здесь.Когда коллекция удаляется или заменяется новой коллекцией, она не может отменить регистрацию обработчика событий, потому что changeFunc - это новый обработчик с другим замыканием.

Итак, как правильно это сделать?

Ответы [ 2 ]

0 голосов
/ 09 декабря 2011

Я решил это с помощью другого присоединенного свойства для хранения частного объекта, содержащего обработчик события и ссылку на d.По сути, я явно создаю класс замыкания и сохраняю ссылку на него.

Но мне кажется, что это довольно сложный подход, я действительно искал более элегантное решение.

0 голосов
/ 02 декабря 2011

Из вашего кода не ясно, где этот статический метод живет.

Есть ли способ сохранить обработчик событий как переменную-член класса, к которому он принадлежит? Это будет единственная ссылка, которая может быть добавлена ​​и удалена при необходимости. В настоящее время вы создаете новый обработчик событий каждый раз, когда срабатывает MyProperty_OnChanged.

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

...