Checking if a specific handler exists

I was wondering if there was a simple way that I can check to see if a specific handler exists for a control. I know I can simply create and set a boolean variable to true once I create the handler, but I was hoping that there was a simple way, without the use of additional variables, to check whether or not the handler has been created:

My control is a TreeView, and is called tvRobot. I create the BeforeSelect handler, tvRobot_AlwaysBeforeSelect, within another event. The problem is, is that I have two handlers for the BeforeSelect event, both of which get created and destroyed throughout the program, so I can't simple check to see if "a" handler exists, I have to check for the specific name, "tvRobot_AlwaysBeforeSelect" in this case.



Answer this question

Checking if a specific handler exists

  • Peter B.L. Rasmussen

    RAB36, you can get the invocation list from outside the class.


  • Delamater

    Hmm... interesting.

    I tried the following in C# 2.0, Visual Studio 2005 and I get an

    error CS0070: The event 'Delegates.Publisher.MyEvent' can only appear on the left hand side of += or -= (except when used from within the type 'Delegates.Publisher')

    class Subscriber

    {

    public Subscriber(Publisher publisher)

    {

    publisher.MyEvent += new EventHandler(publisher_MyEvent);

    foreach (Delegate del in publisher.MyEvent.GetInvocationList())

    {

    Console.WriteLine(del.Method.Name);

    }

    }

    void publisher_MyEvent(object sender, EventArgs e)

    {

    }

    }

    Bernd


  • Maju V Poulose

    No, I can't modify the tvRobot class, because it is a TreeView control object that is on my form. I don't have any access to the TreeView class directly. I could have access of course, if I created a new class that inherited from it, but that is way overkill for what I'm trying to do.


  • BMF

    Thanks, that's pretty much what I figured. It's just that when I program, I try to use as few class level variables/members as possible.


  • er1067

    Then you can just set a flag that you have wired the event. What is wrong with that


  • gb99

    Alex,

    what you can do is accessing the invocation list (list of handlers) of an event in the class the publishes the events and then find out the target object and the method for every entry in the list:

    class Publisher

    {

    public event EventHandler MyEvent;

    public void PrintEventHandlers()

    {

    foreach (Delegate del in MyEvent.GetInvocationList())

    {

    Console.WriteLine(del.Method.Name);

    }

    }

    }

    But this is not possible from outside the class that defines the event. The only thing you could do is wrapping the event of the TreeView by an event of your own and using this event instead of the event of the TreeView.

    Bernd


  • bobe59

    I don't think this will work though. Maybe I'm not understanding your answer, or I didn't explain my question well enough.

    I have a handler (see below) that will get added and subtracted throughout my program. What I want to do, is set up my program to test and see if the handler has been added, so that it doesn't get added more than once.

    tvRobot.BeforeSelect += new TreeViewCancelEventHandler(tvRobot_AlwaysBeforeSelect);


  • Fizgig

    I tried this, but I'm getting an error:

    Error 1 The event 'System.Windows.Forms.TreeView.BeforeSelect' can only appear on the left hand side of += or -= C:\Alex\FlashDrive\Projects\RobotRenderer\RoboArmRobotRenderer13.5\XmlEditor\frmXMLArmEditor.cs 812 58 XmlEditor

    And it is highlighting "BeforeSelect" in "tvRobot.BeforeSelect.GetInvocationList()"

    Is there a reference or a namespace that I'm leaving out I can't seem to get any members to come up in Intellisense when I type dot (.) after "BeforeSelect".


  • DylanG3893

    You can iterate over all wired invocations in the invocation list:


    public void WireBeforeSelectEvent( TreeViewCancelEventHandler invocation )
    {
    bool allreadyWired = false;

    foreach( Delegate wiredInvocation in tvRobot.BeforeSelect.GetInvocationList())
    {
    MethodInfo invocationMethod = invocation.Method;

    if( wiredInvocation.Method.Name.Equals( invocation.Method.Name ))
    {
    allreadyWired = true;
    break;
    }
    }

    if( !allreadyWired )
    {
    tvRobot.BeforeSelect += invocation;
    }
    }



    When you want to wire you method you use it like this:


    TreeViewCancelEventHandler invocation = new TreeViewCancelEventHandler(tvRobot_AlwaysBeforeSelect);
    WireBeforeSelectEvent( invocation );




  • Newbie2007

    Yeah I know I can just create a boolean variable acting as a "flag", but what's wrong with it is that I now have to create another class level member variable to use as a flag, when I shouldn't have to. It's bad coding practice, imo. There should be a way to roll through the event handlers that I've created/added, and find (by name) whether or not a particular one has been created/added.

    Thanks though for all of your help, I really appreciate it:) You taught me some things I never knew about.


  • vcboy

    That a very good practise! Allways try to keep you resources and need at minumum level! But sometime you just need it


  • ricoxxx

    You can only check this in you tvRobot class. Meybe you can better make you event safe, can you modify the tvRobot class


  • Yaron Lavi

    It is a normall approuch to set a flag for such things. In a initialization you wire events, normally you only initialize once.

    You can make a method like this:


    private bool _wired = false;

    public void EnsureWired()
    {
    if( !_wired )
    {
    object.Event += new EventHandler( MyMethod );
    _wired = true;
    }
    }




  • Checking if a specific handler exists