Events for Windows Phone
January 07, 2014
Applies to: Windows Phone 8 | Windows Phone OS 7.1
This topic describes the programming concept of events, and how the event concept works in Windows Phone and its programming models. Windows Phone events are essentially the same event concept as defined by the common language runtime (CLR) and the .NET Framework. Similar to WPF, you can assign handlers for events as part of the declarations for UI elements in XAML, or you can use language-specific syntax to add the handlers in code. Windows Phone supports the concept of routed events, which is a feature whereby certain input events and data events can be handled by objects other than the object that raised the event. Routed events are useful when compositing control templates or when centralizing the event logic of an app page.
This topic contains the following sections.
- Events as a programming concept
- Button.Click: an introduction to using Windows Phone events
- Defining an event handler
- The sender parameter and event data
- Adding event handlers in managed code
- Routed events
- Input event handlers in controls
- User-initiated events
- Removing event handlers
- Related Topics
An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as touching the screen, or it could be triggered by the internal logic of a class. The object that raises the event is called the event sender. The object that captures the event and responds to it is called the event receiver. Basically the purpose of events is to communicate time-specific, relatively lightweight information from an object at run time, and potentially to deliver that information to other objects in the app.
Windows Phone events
Generally speaking, Windows Phone events are CLR events, and therefore are events that you can handle with managed code. If you know how to work with basic CLR events already, you have a head start on some of the concepts involved. But you do not necessarily need to know that much about the CLR event model in order to perform some basic tasks, such as attaching handlers.
Because the UI for a typical Windows Phone-based app is defined in markup (XAML), some of the principles of connecting UI events from markup elements to a runtime code entity are similar to other Web technologies, such as ASP.NET, or working with an HTML DOM. In Windows Phone the code that provides the runtime logic for a XAML-defined UI is often referred to as code-behind or the code-behind file. In the Visual Studio solution views, this relationship is shown graphically, with the code-behind file being a dependent and nested file versus the XAML page it refers to.
In addition to the CLR events that act within its own runtime object model, Windows Phone also has a few events that can invoke script-based handlers on the HTML level, such as OnError. These events are exposed and can be handled by any script working against the plug-in instance in the HTML DOM. As a general event model for an app, HTML scripting should have first chance to do the handling, and if you handle events in an HTML, these events should not be passed on to the managed API.
Because Windows Phone is a UI technology, one of the most common tasks you have is to capture user input to the UI. For example, your UI might have a button that the user must tap to submit information or change your app's state.
Generally, you define the UI for your Windows Phone-based app by generating XAML. This XAML can be the output from a designer such as Blend for Visual Studio or from a design surface in a larger IDE such as Windows Phone. The XAML can also be written out in a plaintext editor or a third-party XAML editor. As part of generating that XAML, you can wire event handlers for individual UI elements at the same time that you define all the other attributes that describe that UI element.
If you are using Windows Phone, you can use design features that make it very simple to wire event handlers from XAML and then define them in code-behind. This includes providing an automatic naming scheme for the handlers.
You can also use the .NET Framework Class Library for Windows Phone documentation to look up a specific event and determine its delegate. The handler you write must be compatible with that delegate signature. For the previously shown example, the best matching delegate is RoutedEventHandler.
Windows Phone event-handler functions cannot be called with parameter values (even empty ones), which is a notable difference from event handler syntax in the HTML DOM. The attribute value in XAML references the handler name only, and other mechanisms, such as the expected input parameters of your handler, pass the information.
For objects that are UI and declared in XAML, event handler code must be defined in the partial class that serves as the code-behind for a XAML page.
Event handlers in the partial class are written as methods, based on the CLR delegates that are used by that particular event. Your event handler methods can be public, or they can have a private access level. Private access works because the handler and instance created by the XAML are ultimately joined by code generation. The general recommendation is to not make your event handler methods public in the class.
Any handler you write for a managed Windows Phone event can access two values that are available as input for each case where your handler is invoked. The first such value is sender, which is a reference to the object where the handler is attached. The sender parameter is typed as the base Object type. A common technique in Windows Phone event handling is to cast sender to a more precise type. This technique is useful if you expect to check or change state on the sender object itself. Based on your own app design, you expect a type that is safe to cast sender to, based on where the handler is attached or other design specifics.
The second value is event data, which generally appears in signatures as the e parameter. Per the CLR event model, all events send some kind of event data, with that data captured as an instance of a class that inherits EventArgs (or is EventArgs itself). You can discover which properties for event data are available by looking at the e parameter of the delegate that is assigned for the specific event you are handling, and then using Intellisense in Visual Studio or the .NET Framework Class Library for Windows Phone. Some Windows Phone events use the EventHandler<TEventArgs> delegate or other generic handler types. In most cases, the event definitions constrains the generic with a specific EventArgs derived event data class. You should then write the handler method as if it took that EventArgs derived event data class directly as the second parameter.
For some events, the event data in the EventArgs derived class is as important as knowing that the event was raised. This is especially true of the input events. For keyboard events, key presses on the keyboard raise the same KeyUp and KeyDown events. In order to determine which key was pressed, you must access the KeyEventArgs that is available to the event handler.
XAML is not the only way to assign an event handler to an object. To add event handlers to any given object in managed code, including to objects that are not even usable in XAML, you can use the CLR language-specific syntax for adding event handlers.
In C#, the syntax is to use the += operator. You instantiate the handler by declaring a new delegate that uses the event handler method name.
If you are using code to add event handlers to objects that appear in the run-time UI, a common practice for Windows Phone is to add such handlers in response to an object lifetime event or callback, such as Loaded or OnApplyTemplate, so that the event handlers on the relevant object are ready for user-initiated events at run time.
The other option for Visual Basic syntax is to use the Handles keyword on event handlers. This technique is appropriate for cases where handlers are expected to exist on objects at load time and persist throughout the object lifetime. Using Handles on an object that is defined in XAML requires that you provide a Name / x:Name. This name becomes the instance qualifier that is needed for the Instance.Event part of the Handles syntax. In this case you do not need an object lifetime-based event handler to initiate attaching the other event handlers; the Handles connections are created when you compile your XAML page.
Sub textBlock1_MouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles textBlock1.MouseEnter '.... End Sub Sub textBlock1_MouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs) Handles textBlock1.MouseLeave '.... End Sub
Visual Studio and its XAML design surface generally promote the instance-handling technique instead of the Handles keyword. This is because establishing the event handler wiring in XAML is part of typical designer-developer workflow for Windows Phone, and the Handles keyword technique is incompatible with wiring the event handlers in XAML.
Windows Phone supports the concept of a routed event for several input events that are defined in base classes and are present on most UI elements that support user interaction and input. The following is a list of input events that are routed events:
A routed event is an event that is potentially passed on (routed) from a child object to each of its successive parent objects in the object tree. The object tree in question is approximated by the XAML structure of your UI, with the root of that tree being the root element in XAML. The true object tree might vary somewhat from the XAML because the object tree does not include XAML language features such as property element tags. In general you can think of the routed events as "bubbling" from XAML object element children that raise the event, toward the parent object element that contains them. The event occurrence and its event data continue and are reported to objects along the event route until the root element is reached. (If you have used certain Web technologies such as DHTML, the "bubbling" concept might already be familiar to you.)
XAML supports an analogous "tunneling" routing strategy, whereby the root of a page / object tree has the first chance to handle a routed event, and the event then "tunnels" down the object tree toward its event source. Windows Phone does not use "tunneling" routed events. Events in Windows Phone either follow the "bubbling" routing strategy (and are referred to as routed events) or do not route at all. There are also other API-level differences in routed event behavior between wphone and XAML.
The OriginalSource property of RoutedEventArgs
When an event bubbles up an event route, sender is no longer the same object as the event-raising object. Instead, sender is the object where the handler that is being invoked is attached. In many cases, sender is not the object of interest, and you are instead interested in knowing information such as object held focus when a keyboard key was pressed. In such a case, the value of the OriginalSource property is the object of interest.
At all points on the route, OriginalSource reports the original object that raised the event, instead of where the handler is attached. For an example scenario where this is useful, consider an app where you want certain key combinations to be "hot keys" or accelerators, regardless of which control currently holds keyboard focus and initiated the event. In terms of the object tree, the focused object might be nested within some items list in a list box, or could be one of hundreds of objects in the overall UI. Having to attach handlers to every possible focusable object in an app to detect your accelerator is obviously impractical. But because the keyboard events are bubbling routed events, the event eventually reaches the root object in its route. Therefore, you can often attach a single KeyDown handler on the root object and rely on the behavior that a KeyDown event eventually bubbles to the root object. Then the handler can determine whether that key is the valid combination for an intended accelerator action, or whether no action is necessary.
Using input bubbling to your advantage is especially useful if you are creating a templated control. Any control that has a template can have a new template applied by its consumer and therefore, might potentially eliminate any event handling declared in the default template XAML. You can still provide control-level event handling by attaching handlers as part of the OnApplyTemplate override in the class definition and catch the input events that bubble up to the control's root.
The Handled property
Several event data classes for specific routed events contain a property named Handled. For examples, see MouseButtonEventArgs.Handled, KeyEventArgs.Handled, , DragEventArgs.Handled, and ValidationErrorEventArgs.Handled. Handled is a settable Boolean property.
Setting the Handled property to true influences the event system in Windows Phone. When you set the value to true in event data, the routing stops for most event handlers; the event does not continue along the route to notify other attached handlers of that particular event case. What "handled" as an action means in the context of the event and how your app responds is up to you. However, you should keep in mind the behavior of the Windows Phone event system if you set Handled in your event handlers.
Not all of the routed events are cancellable in this way. GotFocus, LostFocus, and MouseMove will always route all the way to the root, and their event data classes do not have a Handled property that can influence that behavior. Therefore, checking OriginalSource values for those events is often a good idea, to make sure you are not handling an event and making incorrect assumptions about what the event means and where the input event originated in the UI layout.
The concept of a Handled property for routed events also exists in XAML. In XAML, the Handled property exists on all routed event-data classes; in Windows Phone, only the specific event data classes that have their own Handled property can be used to cancel the related event's route.
Routed events outside the visual tree
Certain objects in Windows Phone participate in a relationship with the primary visual tree that is conceptually like an overlay over the main visuals. These objects are not part of the usual parent-child relationships that connect all tree elements to the visual root. This is the case for any displayed Popup. If you want to handle routed events from a Popup you should place the handlers on specific UI elements that are within the Popup and not the Popup elements themselves. You should not rely on routing inside any compositing that is performed for Popup content. This is because event routing for routed events works only along the main visual tree. Popup is not considered a parent of subsidiary UI elements and never receives the routed event, even if it is trying to use something like the Popup default background as the capture area for input events.
Specific existing Windows Phone controls sometimes use this Handled concept for input events internally. This can give the appearance from user code that an input event never occurs. For example, the Button class includes logic that deliberately handles the general input event MouseLeftButtonDown. Reference topics for specific control classes in the .NET Framework Library often note the event handling behavior implemented by the class. In some cases, the behavior can be changed or appended in subclasses by overriding OnEvent methods. For example, you can change how your TextBox derived class reacts to key input by overriding TextBox.OnKeyDown.
Registering handlers for already-handled routed events
Earlier it was stated that setting Handled to true prevented most handlers from acting. The API AddHandler provides a technique where you can attach a handler that will always be invoked for the route, even if some other handler earlier in the route has set Handled to true. This technique is useful if a control you are using has handled the event in its internal compositing or for control-specific logic but you still want to respond to it on a control instance, or higher in the route. However, this technique should be used with caution because it can contradict the purpose of Handled and possibly violate a control's intended usage or object model.
For more information including a usage example, see AddHandler.
Windows Phone enforces that certain operations are only permitted in the context of a handler that handles a user-initiated event. The following is a list of such operations:
Windows Phone user-initiated events include the mouse events (such as MouseLeftButtonDown), and the keyboard events (such as KeyDown). Events of controls that are based on such events are also considered user-initiated.
API calls that require user initiation should be called as soon as possible in an event handler. This is because the Windows Phone user initiation concept also requires that the calls occur within a certain time window after the event occurrence. In Windows Phone, this time window is approximately one second.
In some circumstances, you might want to remove event handlers during the app lifetime. To remove event handlers, you use the CLR-language-specific syntax. In C#, you use the -= operator. In Visual Basic, you use the RemoveHandler function. In either case, you reference the event handler method name
The following code shows how to remove an event handler named textBlocks_MouseEnter from the target object textBlock1.
You can also remove handlers for cases where the event was added through a XAML attribute. This is easier to do if you provided a Name value for the element where the handler was attached because that provides an object reference for code later; however, you could also walk the object tree in order to find the necessary object reference if you had to.
In Windows Phone, a small number of UI elements support commanding. Commanding uses input-related routed events in its underlying implementation and enables processing of related UI input (a certain mouse action, a specific accelerator key) by invoking a single command handler. If commanding is available for a UI element, consider using its commanding APIs instead of any discrete input events. For more information, see one of the following: