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.
- 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.
- Create a "master" handler method that will actually be attached to the built-in event, and will iterate through MyHandlers and call each one.
- 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.