2

イベントから匿名メソッドのサブスクライブを解除する方法を知りたいです。

私はすでに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);
        }
    }
4

2 に答える 2

2

匿名の代理人ではそれを行うことはできません。登録を解除できるようにするには、通常の代理人を使用する必要があります。

于 2012-06-22T08:27:44.877 に答える
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;
    }
}

ラムダ式は1つしかないので、単一の静的メソッドに変換されると思います。そのため、新しく作成されたデリゲートは元のデリゲートと同じになります。

しかし、私はそれをお勧めしません。自分でメソッドを作成してから、メソッドグループ変換を使用します。

于 2012-06-22T08:32:53.383 に答える