Silverlight Events

.Silverlight Events

"The event model for Silverlight is based on the concept of bubbling events. Under this model an event will travel up the UI element tree until it is handled or it has reached the top."

  1. In the Visual Studio design surface, if you double-click on a control, VS will generate the connection for the control's default event. For example, if you double-click on a button, VS will:
    1. Add the default event (Click="button1_Click") to the xaml definition of the control:

              <Button Name="button1"
                      Content="Button"
                      Height="23"
                      Width="75"               
                      VerticalAlignment="Top"               
                      Click="button1_Click" />

    2. Add the stub for the event handling method (button1_Click) in the code-behind file:

      namespace Events
      {
          public partial class MainPage : UserControl
          {
              public MainPage()
              {
                  InitializeComponent();
              }

              private void button1_Click(object sender, RoutedEventArgs e)
              {

              }
          }
      }

  2. Another option for handling events is have the code-behind file handle everything. That is the event handler is not attached in the xaml, instead we attach the event handler in the code-behind (myBtn.Click += new RoutedEventHandler(myBtn_Click); Below is a coding example of this method.

            <Button Name="button1"
                    Content="Button"
                    Height="23"
                    Width="75"               
                    VerticalAlignment="Top" />

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace Events
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                button1.Click += new RoutedEventHandler(button1_Click);
            }

            private void button1_Click(object sender, RoutedEventArgs e)
            {
            
            }
        }
    }

Handling Routed Events

  1. The event model for Silverlight is based on the concept of bubbling events. Under this model a control can raise an event that will be handled by its parent control. This will continue up the control hierarchy until an event handler declares it has handled the event (e.Handled = true;). Note: Silverlight does NOT support tunnel routing of events (ie. going down the hierarchy). Additionally Silverlight does NOT support user-created bubbling events (new events you create will never bubble).

  2. Not all events support routing. Below is a list of Silverlight's input events that support routing:
    • KeyDown
    • KeyUp
    • GotFocus
    • LostFocus
    • MouseLeftButtonDown
    • MouseRightButtonDown
    • MouseLeftButtonUp
    • MouseRightButtonUp
    • MouseMove
    • MouseWheel
    • BindingValidationError
    • DragEnter
    • DragLeave
    • DragOver
    • Drop
  3. Below is and example of how events can bubble up the control hierarchy. The MouseRightButtonDown event is handled by the nested controls (Rectange, StackPanel, Border, Grid) and since none of the events are coded to declare it has handled the event (e.Handled = true;) the event bubbles up to be handled by the topmost control (Grid=Layout Root).

    Get Microsoft Silverlight


    Event Bubbling Demo (Right-Click on Different Areas)

    MainPage.xaml

    <UserControl x:Class="Events.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="213" d:DesignWidth="297">

        <Grid x:Name="LayoutRoot" Background="White"
              MouseRightButtonDown="LayoutRoot_MouseRightButtonDown"
              Height="131"
              Width="268">
            <Border x:Name="theBorder"
                    Background="Blue"
                    Margin="24,12,34,20"
                    MouseRightButtonDown="theBorder_MouseRightButtonDown">
                <StackPanel Background="Green"
                            x:Name="theStackPanel"
                            MouseRightButtonDown="theStackPanel_MouseRightButtonDown"
                            Height="69"
                            Width="157">
                    <Rectangle x:Name="theRectangle"
                               Fill="Red"
                               MouseRightButtonDown="theRectangle_MouseRightButtonDown"
                               Height="45"
                               Width="85"></Rectangle>
                </StackPanel>
            </Border>
        </Grid>
    </UserControl>


    MainPage.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace Events
    {
        public partial class MainPage : UserControl
        {
            private string message = "";
            public MainPage()
            {
                InitializeComponent();
            }

            private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                message += "Layout handled event\n";
                MessageBox.Show(message);
                message = "";
            }

            private void theBorder_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                message += "theBorder handled event\n";
            }

            private void theStackPanel_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                message += "theStackPanel handled event\n";
            }

            private void theRectangle_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                message += "theRectangle handled event\n";
            }
        }
    }

AddHandler Method

  1. The AddHandler method provides a way to always invoke a specified handler, even if the routed event has already been marked as handled. The AddHandler method can be used at the page level, so no matter if any page control declares it has handled the event, the AddHandler registered routed event will always get called.

  2. The AddHandler method adds a routed event handler for a specified routed vent, adding the handler to the handler collection on the current element. Specify handledEventsToo as true to have the provided handler be invoked for routed event that had already been marked as handled by another element along the event route.

  3. Below is the constructor code from MainPage.xam.cs which contains a call to the AddHandler method, which causes any controls on the page to hande the MouseLeftButtonDownEvent event:

            public MainPage()
            {
                InitializeComponent();
                this.AddHandler(UIElement.MouseLeftButtonDownEvent,
                   new MouseButtonEventHandler (LayoutRoot_MouseRightButtonDown), true);

            }

  4. AddHander Syntax:

    public void AddHandler(
      RoutedEvent routedEvent,
      Delegate handler,
      bool handledEventsToo
    )



Reference Articles


Top