Tag Archives: multicast events

Event handling in WPF

In the last post, we saw how to build a simple WPF application using Expression Blend (EB). In this post we’ll add some event handlers to the controls in that application, and in the process bring Visual Studio (VS) into play.

Load up the project created in the last post into EB. In Objects and Timeline on the left, select the menuFileExit MenuItem. Now look at the Properties panel on the right. We want to add an event handler to this MenuItem so that when the item is clicked, the application shuts down. To open the Events list click on the icon with the little lightning bolt in it (circled in red here):

You should now see a long list of events that can be generated by this MenuItem. We’re interested in only one: the Click event. Find this event in the list (it should be second from the top), and double-click in the text area for this event. This will create an event handler called menuFileExit_Click (assuming you’ve named the MenuItem menuFileExit as we did in the previous post).

If you have told EB to open Visual Studio (VS) to deal with event handling code, VS should now start up and display this bit of code in its C# editor. It may take a while for VS to get going, so be patient at this stage.

Before we move to VS, however, look at the XAML code in EB. The line declaring menuFileExit will now look like this:

<MenuItem x:Name="menuFileExit" Header="E_xit" Click="menuFileExit_Click"/>

Note the addition of a ‘Click’ field at the end. This is XAML’s way of adding an event handler to the MenuItem.

Assuming that VS has now loaded, switch over to it and examine the code in C#. You will see that a method shell has been produced that looks like this:

    private void menuFileExit_Click(object sender, RoutedEventArgs e)
    {

    }

This method will be called whenever the MenuItem is clicked. We want the program to shut down, so we enter the code to make the method look like this:

    private void menuFileExit_Click(object sender, RoutedEventArgs e)
    {
      Application.Current.Shutdown();
    }

‘Application’ is a pre-defined class. Its ‘Current’ field is, not surprisingly, the currently running application, and calling the Shutdown() method will terminate the current application. You can now run the program and shut it down by selecting this menu item.

Next, we want to add an event handler for the button. This is done in the same way: in EB, select the button in Objects and Timeline, display its list of events, and double-click the Click event. This will take you back to VS, where you can enter the code to display the current date and time in the status bar.

    private void buttonDateTime_Click(object sender, RoutedEventArgs e)
    {
      textStatusBar.Text = DateTime.Now.ToString("dddd, dd MMMM yyyy hh:mm:ss tt");
    }

We’ve used the built-in DateTime class, whose Now field generates the date and time when it is called. There are a huge number of ways the date and time can be formatted, and the one given here is just a sample. It gets very tedious to describe all the various formats (and you’ll just forget them before the next time you’ll need them anyway), so it’s good practice to use Google to find a page that documents them. Just search for keywords like “DateTime WPF format” and you should find several pages that list them all. For the record, here’s what the format above looks like in the status bar, after the button is pressed:

That’s all you need to know to write a few simple WPF programs and attach event handlers to them.

However, there’s one feature of event handlers that’s worth a mention at this point, even though it’s not something you’ll use all that often. It does, though, give you a bit more insight into how you can deal with event handlers in your own code.

Event handlers in .NET are, in technical jargon, multicast delegates. Essentially what this means is that one event can call multiple event handlers. The technique we’ve seen so far allows you call only one handler, so how do you get an event to handle more than one?

As far as I know (I stand to be corrected if anyone knows better), it is not possible to add more than one handler for an event in XAML code, so you need to do it in the C# portion of the project. As an example, suppose we want to add an extra handler to the button. (OK, in practice you’d usually just put all your handling code in one method, but this is just for illustration.)

Despite all the fancy debugging and code tracing tools included in VS, I find a good, simple way of debugging a program is to put output statements at various places in the code so you can see where the program is going as it runs. In order to do this in VS, a simple way is to make the program a “Console application” so you get one of those little black console windows appearing alongside the GUI window. To do this in VS, (assuming your project is called DateTimeApp) open the Project menu and click on the last item in this menu, named “DateTimeApp properties”. In the window that appears, change the Output type to “Console Application” and then run your program again. You’ll now get a console alongside the main window. When you’re done debugging, just switch the Output type back to “Windows Application” to get rid of the console window.

The reason for doing all this is so we can add an extra event handler to the button that prints out a console message. Back in the C# file, add a method like this:

    private void buttonDateTime_Click_Extra(object sender, RoutedEventArgs e)
    {
      Console.WriteLine("buttonDateTime_Click_Extra called");
    }

Console.WriteLine() just prints the string to the console.

Now we need to get the button to call this method in addition to the buttonDateTime_Click() method it already calls. To do this, add a line of code in the MainWindow() constructor

    public MainWindow()
    {
      this.InitializeComponent();

      // Insert code required on object creation below this point.
      buttonDateTime.Click += buttonDateTime_Click_Extra;
    }

You can see that the += operator is used to add another event handler to buttonDateTime’s Click event. Be sure to put this code after the call to InitializeComponent(); otherwise buttonDateTime won’t be created and you’ll get a null reference error.

If you now run the program and then click the button, you’ll see that the date is updated in the status bar and a message is printed in the console. This demonstrates that you can add event handlers in both the XAML and C# sections of the code.

Advertisements