Events in DFL
There are different aspects to events in DFL:
- The Event template type - keeps track of event handlers for this event and allows them to be called.
- Event handler - user-defined callback delegate that is attached to the Event to be called when the event fires. These usually contain sender and event-argument information.
- onEvent method - contains the object's base functionality for the event, and fires the Event which calls the attached event handlers.
To override or not to override?
That is the question. You may be wondering, "do I override the onEvent, or do I attach to the Event with ~=" If you follow these guidelines, you should be set:
- Override onEvent when you are adding to the object's functionality, such as creating a UrlButton type that launches a URL on-click.
- Attach to the Event with ~= when you simply want to react to an event of another object, such as using a regular Button to launch your URL on-click.
You may be thinking it's the same thing, but notice the first example is implementing base functionality, but the second one is attaching to an existing object that has different functionality (more generic in this case).
So, in other words, you generally do not want to use onEvent unless you are making a reusable type.
Precautions when overriding
You need to be careful when overriding onEvent; you should always call super.onEvent unless you have good reason not to, because you may be breaking features from the base class that depends on the method being called, and the event's attached event handlers won't fire unless you call it yourself.
Attaching to an event
At last, how to attach to an event. First of all, I should mention that the DFL download comes with many examples that show events in action; the installer will put a shortcut to the examples into your start menu.
The Event template type allows you to attach event handlers using the ~= operator (opCatAssign). To be on the safe side, your event handler callback delegate should always be a class method / member function. The parameters of the event handler function are contravariant, allowing more general or specific types to be used as you prefer.
DFL's Button class inherits event click from Control and is defined to take parameters Control and EventArgs, or contravariance allows you to use Object and EventArgs as well if you wish.
Below is an example Form with a button on it and pops up a message box when the button is clicked.
class MyForm: Form
{
Button myButton;
this()
{
myButton = new Button();
myButton.text = "Click Me";
myButton.click ~= &myButton_click;
myButton.parent = this;
}
private void myButton_click(Control sender, EventArgs ea)
{
msgBox("You clicked the button!");
}
}
After adding the proper import and main
function, it will compile and work like the below image.