Windows Phone Fundamentals–3 Ways To Handle Events

Windows Phone From Scratch

One potential area of confusion for programmers new to Silverlight and Windows Phone is EventHandlerDemo that there are (at least) three distinct ways to handle events. 

  • Name the event handler in the Xaml
  • Name the event handler in the constructor
  • Use an anonymous delegate via a Lambda expression

Let’s review all three. To do this, we’ll need a new application with a TextBox, a Button and a TextBlock.  When the button is pressed the text from the TextBox (entered by the user) will be written into the TextBlock and the TextBox will be cleared. 

To start, create a new Windows Phone application and add two rows, the first with a TextBox and a Button (and therefore, within a StackPanel) and the second with a TextBlock.  Make sure you understand why you need a StackPanel (if not, see this article). 

Here’s the Xaml you’ll need,

 <!--ContentPanel - place additional content here-->
 <Grid
     x:Name="ContentPanel"
     Grid.Row="1"
     Margin="12,0,12,0">
     <Grid.RowDefinitions>
         <RowDefinition
             Height="1*" />
         <RowDefinition
             Height="1*" />
         <RowDefinition
             Height="4*" />
     </Grid.RowDefinitions>
     <StackPanel
         Grid.Row="0"
         HorizontalAlignment="Stretch"
         VerticalAlignment="Stretch"
         Orientation="Horizontal">
         <TextBox
             Name="NewText"
             Width="300"
             Margin="5" />
         <Button
             Name="ShowText"
             Content="Show"
             Margin="5" />
     </StackPanel>
     <TextBlock
         Name="Message"
         Grid.Row="1"
         HorizontalAlignment="Stretch"
         VerticalAlignment="Stretch"
         Margin="5"
         Text="Ready..." />
     
 </Grid>

 

Adding The Event Handler In The Xaml

The first of the three ways to manage the event handler is to add it to the Xaml. Since the event is the Button being clicked, you add a click event handler name toEventsButton the Button itself.

The very best way to do this is to click on the Button and then to go to the properties Window and click on the Events Button (see figure).   Find the Click Event and double click in the text box in the right hand column. 

Visual Studio will create an event handler name for you ( in the pattern: ControlName_EventName, in this case ShowText_Click) and will also create the stub of the event handler in the code behind, and place you within the event handler.  You have then only to fill in the event semantics,

private void ShowText_Click( object sender, RoutedEventArgs e )
{
   Message.Text = NewText.Text;
   NewText.Text = string.Empty;   
}

Take a look at the Xaml and you’ll see that Visual Studio has identified the event handler in the Xaml for the Button.

<Button
    Name="ShowText"
    Content="Show"
    Margin="5"
    Click="ShowText_Click" />

 

Adding the Event Handler In Code

An alternative to  the above, and one I personally prefer, is to have all the event handlers identified in code. The simplest way to do this is to name the event handler in the constructor. Once again, Visual Studio will be tremendously helpful.  When you type the name of the control (ShowText) Intellisense will pop up with the name of all the events.

Choose click and enter += followed by a space. Once again, Intellisense will pop up and EventHandler offer to create the event handler for you. Press tab to accept and Intellisense will now offer to name the event handler for you.  Press tab and Visual Studio completes the identification of the event handler, stubs out the event handler and places you within the event handler to complete the code.

ShowText.Click += new RoutedEventHandler(ShowText_Click);

 

It turns out, by the way, that Visual Studio is being very conservative. Since these event handler types are already declared (within the hidden part of the class) you can actually shorten your event handler declaration to,

ShowText.Click +=  ShowText_Click ;

 

Using A Lambda Expression

It is becoming increasingly common to use a Lambda Expression to create the event handler in line within the constructor, rather than calling a separate event handler.  While I see the benefit of doing this when the event handler is a single line, it does seem to clutter the constructor with anything larger. Nonetheless, here is how you would write this event handler, using a Lambda expression:

public MainPage()
{
    InitializeComponent();
    ShowText.Click += ( o, e ) =>
    {
        Message.Text = NewText.Text;
        NewText.Text = string.Empty;
    };
}

 

The syntax here requires an understanding of Lambda Expressions.

First, you read it as “ShowText’s click method adds an event handler that receives two parameters, o and e. o and e goes to (=>)… the contents of the braces. 

You can map a Lambda Expression back to a method as follows:

  • What is in the parentheses maps to the arguments of the method
  • What is in the braces maps to the body of the method

thus, you can imagine that this Lambda expression maps to an (unnamed) method that might look like this,

private void Unnamed( object o, RoutedEventArgs e )
{
   Message.Text = NewText.Text;
   NewText.Text = string.Empty;   
}

 

All three of these approaches work and are perfectly valid. Which you use is entirely a matter of personal taste.

Share

About Jesse Liberty

Jesse Liberty is an independent consultant and programmer with three decades of experience writing and delivering software projects. He is the author of 2 dozen books and multiple Pluralsight courses, and has been a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Xamarin Certified Mobile Developer and a Xamarin MVP, Microsoft MVP and Telerik MVP.
This entry was posted in Essentials, Languages, Mini-Tutorial, Patterns & Skills, WindowsPhone and tagged . Bookmark the permalink.

12 Responses to Windows Phone Fundamentals–3 Ways To Handle Events

  1. Gladis says:

    I read a lot of interesting content here. Probably you spend a lot of time writing, i know
    how to save you a lot of work, there is an online tool that creates high quality,
    SEO friendly posts in minutes, just search in google
    – laranitas free content source

  2. I must tell you that it’s hard to find your articles in google,
    i found this one on 17 spot, you should build some quality backlinks in order to
    rank your webiste, i know how to help you, just type in google – k2 seo tips and
    tricks

  3. Pingback: Windows Phone Fundamentals – 3 Ways To Handle Events – www.nalli.net

  4. Peter Wone says:

    Use of lamba expressions to assign event handlers inline like this is symptomatic of having missed the point of lambdas, which is scope inclusion. Any variable visible to your code at the point where the lambda expression is resolved will be visible in the expression’s code. This even includes variables local to the stack frame in use at the time the anonymous delegate is realised.

    This makes lambdas absolutely perfect for using APM with things like TCP listener sockets, because instead of creating a class to contain various elements of session state you can just declare them as locals and use a lambda; they will be lifted into scope for the lambda code block. At the end of the handler when you declare another lambda and pass it to NetworkStream.BeginRead, all your session state magically remains available. No locking is required: only one thread at a time will ever have access to this state. No explicit state management code is required. It’s beautiful.

  5. Philip the Duck says:

    The general rule for deciding whether you need to detach event handlers in a page is if the object whose event you’re handling is longer-lived than your page object, or static, such as NetworkChange.NetworkAddressChanged. If you don’t detach from the longer-lived object’s event your page will be kept around until that object is itself garbage-collected, or forever in the case of static events! Each time the user visits your page a new instance will then be created, resulting in a memory leak.

    The event to be most wary of, though, is the DispatcherTimer.Tick event. Even though you may create a DispatcherTimer in your page (which of course can’t be longer-lived than your page since it’s owned by your page), once you hook its Tick event a reference to your event handler (and therefore to your page object) is added to the dispatcher’s internal timer list, which is static.

    So, if you don’t unhook the Tick event (or call DispatcherTimer.Stop(), which internally removes your handler from the dispatcher’s timer list), your page instance will be kept around forever and, as mentioned above, a new instance will be created each time the user visits that page, resulting in a potentially major memory leak.

    It is therefore a good idea not to use a lambda (or an anonymous delegate, as shown on the DispatcherTimer.Tick MSDN doc page) to hook a DispatcherTimer.Tick event, since you can’t get a reference to that anonymous method to unhook the event, which results in the memory leak mentioned above (unless, of course, you call DispatcherTimer.Stop(), as also mentioned).

    Hope this helps!

    Reference:
    DispatcherTimer.Tick
    NetworkChange.NetworkAddressChanged

  6. Steve says:

    Why not?

  7. Pingback: Windows Phone Fundamentals–3 Ways To Handle Events | WP7 Developers Links

  8. Pingback: Anonymous

  9. Brian says:

    Do you need to worry at all about detaching event handlers?

      • A better answer for this is, “I generally don’t worry about detaching event handlers as it is rare that I don’t want the event handler in place for the life of the program. If you do have an event handler that need be in place only for a short while, you may want to detach it. Because each event handler is created in the constructor for the page, the event handler is released when the page goes out of scope or is otherwise destroyed.”

        Hope that helps.

        -j

Leave a Reply

Your email address will not be published.