Events

In progrmaming, an event is how we generally refer to actions that the user takes. When they open the program, click a button, select an option from a list of radio buttons, or type in their e-mail address, these are all broadly classified as events. It will often be upon ourselves to build the program to respond to many of these events, in either visible ways to the user ("Your password must contain at least one numeric digit, one astrological sign, and one line of lyrics from 'Never Gonna Give You Up' by Rick Astley") or in ways hidden from the user ("Daniel's purchased a lot of blu-ray movies starring Karen Gillian... maybe we'll suggest this one he hasn't bought yet." Such a movie doesn't exist, by the way — I own them all!). Handling events is one of the most effective ways to create software that dynamically responses to the user, enabling a sense of immersion with whatever process is taking place. This immersion is vital for keeping users engaged with the software.

There are two "actors" when it comes to events: the publisher (the class which broadcasts the occurrence of an event), and one or more subscribers (other class(es) that response to the event). So for example, a Form may detect a ButtonClick event, which a Handler may respond with by incrementing an invisible counter of how many times a ButtonClick event occurred. Once the counter reaches 42, a pop-up window is spawned, reminding the user to not forget their towel.

Now, because there can be multiple subscribers, each of whom will want to respond to the broadcast of an event, you might have guessed that use of a delegate can help organize this. Indeed, events are a special kind of multicast delegate that can only be invoked from within the struct or class in which they are defined. The subscribers will add their method to the linked list invoked by this multicast delegate. By convention, we code these multicast delegates with a name ending in "Handler".

There are a lot of moving parts when it comes to correctly implementing a publisher/subscriber relationship in your program, so you'll want to devote some time to making sure you understand the fundamental mechanics and syntax. Let's break down one example, from the one I mentioned above referring to Douglas Adams' famous novel, The Hitchhiker's Guide to the Galaxy.

public namespace ManyEventsHandleIt
{
public class FunnyEventArgs : EventArgs // This is how I transmit information about the event
{
public int HowMany { get; set; } // Auto-implemented
public DateTime TimeStamp { get; set; }
}

public class TowelCounter // This will be my publisher class
{
private readonly int life = 42;
public int total;
public event EventHandler<FunnyEventArgs> TheJoke;

public TowelCounter() : total(0) { }

// This method will broadcast the event to subscribers
protected virtual void TimeForTheJoke(FunnyEventArgs argData)
{
  EventHandler<FunnyEventArgs> handler = TheJoke;
if (handler != null)
{
handler(this, argData); // The first argument will almost always be "this"
}
}

public void step() // This simple mechanism is what will ultimately trigger this event
{
total++;

if (total >= life) // Time to let the people know!
{
  FunnyEventArgs args = new FunnyEventArgs();
args.HowMany = (total - life) + 1;
args.TimeStamp = DateTime.Now;

// Finally, we'll call the method that invokes the handler
TimeForTheJoke(args);
}
}
}

public class MyJokeProgram
{
// Here is one of my subscribers
static void JokeHandler(object sender, FunnyEventArgs args)
{
if (args.HowMany > 1)
MessageBow.Show("Don't forget to bring your {0} towels!", args.HowMany);
else if (args.HowMany == 1)
MessageBow.Show("Don't forget to bring your towel!");
}

  public TowelCounter towel;

public JokeWindow()
{
towel = new TowelCounter();

// This next line will attach the subscriber to publisher
towel.TheJoke += JokeHandler;
myButton.Click += new EventHandler(this.myButton_ClickEvent);
}

public void myButton_ClickEvent(Object sender, EventArgs args)
{
towel.step();
}
}
}


I color-coded this because the example I was reading from was horrendously disorganized, so this helped me keep all the bits straight. If it helped you too, that's even better. And sort of the whole point of these class notes...

It won't take us long to begin implementing various EventHandlers and indeed, if you go on to work in this industry, you can expect there to be plenty of iterations of this type of code. So it would not at all be a waste of your time to closely and carefully study this code, practice its implementation, and then practice some more. It will do wonders for your productivity if you can bust out most of this code without having to refer back to MSDN documentation and/or old source code.