2012-06-22 4 views
2

Я хочу знать, как отменить анонимные методы из событий.Отказаться от подписки на анонимный делегат

Я уже проверил Unsubscribe anonymous method in C#, но мой случай немного отличается.

Я получаю доступ к локальной переменной функции в анонимном методе.

код, как показано ниже

private static void Test(Object dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) 
    { 
     if (dependencyPropertyChangedEventArgs.OldValue is ObservableCollection<object>) 
     { 
      (dependencyPropertyChangedEventArgs.OldValue as ObservableCollection<object>).CollectionChanged -= 
       (s, e) => SelectedItemsChanged(dependencyObject, e); // TO FIX event unbsubscription via anonymous delegate 
     } 

     if (dependencyPropertyChangedEventArgs.NewValue is ObservableCollection<object>) 
     { 
      (dependencyPropertyChangedEventArgs.NewValue as ObservableCollection<object>).CollectionChanged += 
       (s, e) => SelectedItemsChanged(dependencyObject, e); 
     } 
    } 
+1

В каком случае ваш случай отличается? Вы просто не можете этого сделать - это не сработает. См. Также http://stackoverflow.com/questions/1348150/how-do-i-unregister-anonymous-event-handler. –

+0

Разница в том, что мне нужно обеспечить доступ переменной к локальной функции. Как передать эту переменную, если я решил использовать именованный метод. – Tilak

ответ

1

Новый ответ, теперь вопрос изменился

Вы не можете, в принципе. Ваш обработчик зависит от dependencyObject, который будет захвачен в новом объекте при каждом вызове, поэтому вы получите неравные делегаты.

Вы можете создать новый класс, который содержит объект зависимостей и переопределяет Equals сравнить эти объекты вместо того, чтобы использовать анонимные функции, или вы можете просто держать ссылку на ранее подписался обработчик.


Старый ответ, когда делегат не зависит от параметров

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

private static void Test(Object a, DependencyPropertyChangedEventArgs args) 
{ 
    NotifyCollectionChangedEventHandler handler = 
     (s, e) => SelectedItemsChanged(dependencyObject, e); 

    var oldObservable = args.OldValue as ObservableCollection<object>; 
    if (oldObservable != null) 
    { 
     oldObservable.CollectionChanged -= handler; 
    } 
    var newObservable = args.NewValue as ObservableCollection<object>; 
    if (newObservable != null) 
    { 
     newObservable.CollectionChanged += handler; 
    } 
} 

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

Однако я бы не стал рекомендовать что. Я просто создаю метод самостоятельно, а затем использую преобразование группы методов.

+0

В моем вопросе была опечатка. Первым параметром должен быть параметр dependencyObject (не a). Как использовать преобразование группы методов (и передать зависимость метода к методу)? – Tilak

+0

@ Тилак: В этом случае вы не можете, и вместо этого вы должны сохранить обработчик. Я отредактирую. –

+0

@ Тилак: В будущем, пожалуйста, не редактируйте мои ответы, когда изменение существенно повлияет на смысл. Результатом был код, который * не работал бы, и который также не гель с моим описанием. –

2

Вы не можно сделать с помощью анонимных делегатов. Для того, чтобы иметь возможность отказаться от подписки вы должны использовать обычный делегатов.

Смежные вопросы