Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to determine if a delegate is 'empty'

Status
Not open for further replies.

esdee

Programmer
Apr 12, 2001
143
US
controlButton.Click += new System.EventHandler(this.controlButton_StopClick);

how can i check if Click has not already been wired with a method in order to avoid multiple invoking of controlButton_StopClick ?

------------------------
 
You need to override the Button class and do the following:

1) Add a private boolean variable to that class in order to determine that the delegate was already set or not:

Code:
private bool bAlreadyset = false;


2) Re-define the event handler like this:
Code:
public event EventHandler Click
{
    add
    {
        lock (this)
        {
            if (!bAlreadyset)
            {
                this.Click += value;
                bAlreadyset = true;
            }
            else
            {
                //throw an exception if you need to
            }
        }
    }
    remove
    {
        lock (this)
        {
            this.Click -= value;
            bAlreadyset = false;
        }
    }
}


This will ensure that the invocation list of this multi-cast delegate contains only one item, the first one that you set.
 
In your method that calls the listeners to your event, you'd do something like this:
Code:
// The delegate (method signature) that event handlers must follow
public delegate void ChangedEventDelegate(object sender, EventArgs e);

// The event that people will subscribe to
public event ChangedEventDelegate ChangedEvent;

protected void FireChangedEvent(MyEventArgs e)
{
  if (this.ChangedEvent != null)
  {
    foreach(ChangedEventDelegate d in this.ChangedEvent.GetInvocationList())
    {
       try
       {
         d(this, e);
       }
       catch
       {
          // Do nothing, as the subscribers are responsible
          // for handling exceptions in their handlers.  We
          // just have this try..catch here as a safety net
          // in case someone forgets.  It will allow us to
          // proceed to the next invocation target.

          // But we might want to log it anyway, so we can
          // smack the developer who forgot their try block
       }
    }
}
Chip H.

____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
thank you, guys!
im surprised that overiding the class is the only way though :(

by the way - chip: how does this ensure that the handler is called only once? from what i see what you've posted calls each registered handler as many times as it's been added

------------------------
 
Actually, I misunderstood what you needed. The thing you need is to override the System.Windows.Forms.Button ( yup... [ponder] ) class and add to that class a variable like this:

Code:
ArrayList arInvocationList = new ArrayList();

Then, using the new keyword, override the Click event like this:

Code:
      public [b]new[/b] event EventHandler Click
      {
         add
         {
            lock (this)
            {
               if ( !arInvocationList.Contains( value))
               {
                 this.Click += value;
               }
               else
               {
                  //throw an exception if you need to
               }
            }
         }
         remove
         {
            lock (this)
            {
               this.Click -= value;
               arInvocationList.Remove( value);
            }
         }
      }

This will ensure that a delegate isn't registered twice. We need the arInvocationList member because having add and remove accessors for the Click event means that we cannot access it inside these accessors (infinite loop).
 
by the way - chip: how does this ensure that the handler is called only once? from what i see what you've posted calls each registered handler as many times as it's been added
No it doesn't. If a developer registeres for a callback twice, that's another situation where a smack is called-for.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top