更改订阅活动的代理人的目标

时间:2014-03-30 10:18:10

标签: c#

我有一个想法是更改委托的目标,而不是订阅/取消订阅该事件。

我使用TextBox控件的实例(简单单例):

public partial class MyControl : UserControl
{
    private delegate void myKeyUpEvent(object sender, KeyEventArgs args);
    private myKeyUpEvent delKeyUp = (s, k) => { }; // empty starting delegate

    private static MyControl Instance = new MyControl(); 

    private MyControl()
    {
        InitializeComponent();
        myTextBox.KeyUp += new KeyEventHandler(delKeyUp); // add my delegate
    }

    public static void ChangeAction(Action<KeyEventArgs> keyAction = null)
    {
        if (keyAction != null) Instance.delKeyUp = (s, k) => { keyAction(k); };
    }
}

然后我想在我的主线程中使用它:

MyControl.ChangeAction((k) => { Deployment.Current.Dispatcher.BeginInvoke(() => { MessageBox.Show("Works!"); }); });

事实证明它没有按照我的意愿工作。事件发生时,我没有收到任何消息。

是否可以更改订阅活动的代表的目标?

1 个答案:

答案 0 :(得分:2)

更改delKeyUp的值不会更改KeyUp事件的处理程序。

您必须首先删除当前的处理程序,然后添加一个新处理程序。

private static KeyEventHandler _keyEventHandler;

public static void ChangeAction(Action<KeyEventArgs> keyAction)
{
    if (keyAction == null)
        throw new ArgumentNullException("keyAction");

    //create KeyUp handler
    MyKeyUpEvent newKeyUpEvent = (s, k) => { keyAction(k) };
    KeyEventHandler newKeyEventHandler = new KeyEventHandler(newKeyUpEvent);

    //Assign handler
    myTextBox.KeyUp -= _keyEventHandler;
    myTextBox.KeyUp += newKeyEventHandler;

    //keep reference to new handler
    _keyEventHandler = newKeyEventHandler;
}

由于您必须跟踪当前的KeyUp处理程序,因此您还必须更改构造函数。

private MyControl()
{
    InitializeComponent();
    _keyEventHandler = new KeyEventHandler(delKeyUp); // add my delegate
    myTextBox.KeyUp += _keyEventHandler;
}

此外:

  • 如果参数不存在,如果你不做任何事情,那么让keyAction参数可选是没有多大意义的。
  • 请注意,这不是线程安全的。