开发者

C# + Programmatically Working with Event Handlers

I have a TextBox that has the TextChanged event set declaratively. In some cases, I want programmatically set this value. In these cases, I want to disable the TextChanged event until I'm done programmatically setting the value. Then, when I'm done, I want to restore the event handler to behave as it was.

For a single TextBox, I know I can accomplish this by doing the following:

myTex开发者_Python百科tBox.TextChanged -= myTextBox_TextChanged;
myTextBox.Text = "[Some Value]";
myTextBox.TextChanged += myTextBox_TextChanged;

However, I want to write this functionality into a single method that can be accessed by several methods. For instance, I'm trying to do so something like the following

private void UpdateTextValue(TextBox textBox, string newValue)
{
  object eventHandler = textBox.TextChanged;
  textBox.TextChanged -= eventHandler;
  textBox.Text = newValue;
  textBox.TextChanged += eventHandler;
}

Unfortunately, this approach doesn't work. It won't even compile. Is there a way I can encapsulate the functionality I'm trying to accomplish in a method such as the one shown above? If so, how?

Thank you,


You can't, basically. The only functionality an event exposes is subscribe and unsubscribe - you can't ask for the set of existing handlers. If the existing handler is in your code, you could set some flag meaning "ignore any changes raised for the moment" - but you can't effectively remove all the other handlers.


I think Jon's right. However, I think you're approaching the problem from the wrong angle.

In a case like this, where you're actually trying to change the behaviour of a TextBox, my preference would be to sub-class TextBox, add a boolean flag FireOnTextChanged and only fire the event if the boolean value is true. That way you don't have to worry about loading and/or unloading the event handlers.


You could create a derived Textbox, override the TextChanged event to capture the handler Add/Remove calls.

public MyTextbox:Textbox
{
    public Event EventHandler TextChanged
    {
        add
        {
           //set the base
           //store locally
        }
        remove
        {
           //remove from base
           //remove from local store
        }
    }

    public string Text
    {
        get
        {
            //return the base
        }
        set
        {
           //remove local handlers from base
           //set value in base
           //reassign handlers.
        }
    }
}


See MulticastDelegate

I'm not sure but I think it's possible to do something like:

    Delegate[] invocationList = TextChanged.GetInvocationList().Clone();
    foreach (EventHandler h in invocationList) {
        try {
            TextChanged -= h
        } catch (Exception exception) {
            Console.WriteLine(exception.Message);
        }
    }
    foreach (EventHandler h in invocationList) {
        try {
            TextChanged += h
        } catch (Exception exception) {
            Console.WriteLine(exception.Message);
        }
    }

UPDATE

Clone() comes from using System.Linq;

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜