Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding own event handler in front of other event handlers

When I utilize AddHandler in VB to add my own method to the Click event :

  AddHandler Button.Click, AddressOf myButton_Click

I see that my code executes last - after other event handlers for the Button_Click event. Is there a way to insert my event handler in front of other events so that it executes first?

I tagged this question as C# as well as VB, please feel free to use eitherlanguage if you have any suggestions.
Thanks!

like image 657
Meringros Avatar asked Sep 24 '10 17:09

Meringros


People also ask

Can you have multiple event handlers?

Only one event handler can be assigned for every event in an element. If needed the handler can be replaced by assigning another function to the same property. Below we show how to set a simple greet() function for the click event using the onclick property.

Can multiple event handlers be added to a single element?

You can add many event handlers to one element. You can add many event handlers of the same type to one element, i.e two "click" events. You can add event listeners to any DOM object not only HTML elements.

What is inline event handler?

An event handler is a JavaScript function that runs when an event fires. An event listener attaches responsiveness to a given element, which allows the element to wait or “listen” for the given event to fire. Events can be assigned to elements via inline event handlers, event handler properties & event listeners.

Which of the following methods helps us to attach one or more event handlers to a selected element?

on() Attach an event handler function for one or more events to the selected elements.


2 Answers

Not easily.

That being said, don't do it. Your code shouldn't care about what order it's called in - it should just care that the button in question was clicked. All of the handlers, including yours, will execute. If the order is important, you should rethink your design, and use some other mechanism to control that.

like image 85
Reed Copsey Avatar answered Oct 11 '22 15:10

Reed Copsey


The order of execution of handlers of a single event cannot be controlled through the basic behavior of a built-in event itself. MulticastDelegates are "bags" of handlers, and they just grab them one at a time. Keep in mind that this is how most developers expect this to work, and it can be dangerous to allow order-dependent event handlers. Event handlers should normally not know about each other, because if they are dependent on being executed before or after another handler, they first have to know of the existence of the other handler (violating information hiding and several other design principles), and second, if that order changes, the behavior will be broken.

If you understand all this, and still want to control the order of execution of handlers of an event, the following will get you close.

  1. Create an ordered collection of delegates of the event handler type called MyHandlers. This will be a surrogate for the actual event's MulticastDelegate implementation.
  2. Create a "master" handler method that will actually be attached to the built-in event, and will iterate through MyHandlers and call each one.
  3. Define some means to add and remove handlers from the list. Some of this can be accomplished with a custom event "property", but that will define only add and remove behaviors, not insert.

The code might look like the following:

private List<EventHandler> MyHandlers = new List<EventHandler>();

private void MasterClickHandler(object sender, EventArgs e)
{
   foreach(var handler in MyHandlers)
      handler(sender, e); 
}

public event EventHandler MyControlButtonClick
{
   add { MyHandlers.Add(value); }
   remove { MyHandlers.Remove(value); }
}

public void InsertButtonClickHandler(EventHandler handler)
{
   MyHandlers.Insert(handler,0); //calling this to add a handler puts the handler up front
}

...

myForm.MyControl.Click += MasterClickHandler;

Notice that you're no longer attaching handlers other than MasterClickHandler to the actual event; you can't have your cake and eat it too, both overriding and keeping the basic event behavior. There also isn't an "insert" behavior built into the event "property"; you have to define a method that allows this. Lastly, you should never raise the event MyControlButtonClick directly (though as your control is the only one that can, this can be enforced by code inspection).

Now, when you click the button, the button's built-in Click event fires MasterEventHandler, which will execute the delegates in MyHandlers in the same order they were attached to MyControlButtonClick (with any that were inserted executed first, in the reverse order they were inserted). If you placed this code in a custom user control with the Button, you could even name the custom event on your control Click, and the control would look and work much like the Button it contains, except that it would have the extra control over inserting handlers. The beauty of the whole thing is that nothing about this code forces consumers to work with it as anything other than a plain ol' vanilla event.

like image 32
KeithS Avatar answered Oct 11 '22 17:10

KeithS