Published articles on other web sites*

Published articles on other web sites*

Binding Events to Methods in the Silverlight MVVM View Models

Introduction

This article introduces a simple method to bind UI events to the corresponding methods in the MVVM view models in Silverlight applications.

Background

In order to fully conform to the MVVM design pattern in Silverlight, we may want to move the event handling functions into the view models. Generally speaking, we have two types of UI components and two types of UI events in Silverlight applications.
  • UI controls like a Button have a property called Command. We can create a command property in the view model to handle the click event of the button by binding this command property in the view model to the button control's command property in the XAML. For detailed information about the command bindings, you can take a look at my recent article, "Data and Command Bindings for Silverlight MVVM Applications".
  • Unfortunately though, most of the UI events like "MouseEnter", "MouseLeave", and "SizeChanged", etc. do not have the corresponding Commands, we are unable to implement the ICommand interface to handle these events in the MVVM view models.
This article is to introduce a method to bind these events to the corresponding methods in the view models in Silverlight applications, so we can implement all the event handling functions in the view models, thus minimizing the code-behind files of the XAML views.
SolutionExplorer.JPG

The attached Visual Studio solution is developed in Visual Studio 2010 and Silverlight 4. This solution has two projects.
  • The "EventBindingExample" project is the Silverlight application. In this project, I will be demonstrating how to bind UI events from the XAML views to the methods in the view models.
  • The "EventBindingExampleWeb" project is an ASP.NET project to host the Silverlight application. The Silverlight application is hosted in the "EventBindingExampleTestPage.aspx" page. The "EventBindingExampleWeb" project is the default Silverlight host web project created by the Visual Studio.
To use the event binding method in this article, you need the "Microsoft Expression Blend SDK". If you have not done so, you need to download the SDK and install it on your computer. In particular, to bind the UI events to the corresponding methods in the view models, you need to add a reference to the "Microsoft.Expression.Interactions.dll", which comes with the Blend SDK. You will also need to add a reference to the "System.Windows.Interactivity.dll".
After adding the references to these two DLLs, binding UI events to the methods in the Silverlight view models becomes very simple. We will now take a look at the implementations of the Silverlight project "EventBindingExample" to find out how the event binding is achieved. We will first take a look at the view model.

The View Model

The "EventBindingExample" project is a simple Silverlight application, which does not have a data model. The following is the view model class "MainPageViewModel" implemented in the "ViewModels\MainPageViewModel.cs" file.
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
 
namespace EventBindingExample.ViewModels
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        // Implementation of INotifyPropertyChanged interface
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
 
        // Properties
        private string displayText;
        public string DisplayText
        {
            get { return displayText; }
            private set
            {
                displayText = value;
                NotifyPropertyChanged("DisplayText");
            }
        }
 
        // Public methods
        public void WndSizeChanged(object sender, SizeChangedEventArgs e)
        {
            DisplayText = "Window height: " + e.NewSize.Height.ToString()
                + " Window Width: " + e.NewSize.Width.ToString();
        }
    }
}
Besides implementing the INotifyPropertyChanged interface, it has a public property and a public method.
  • The property "DisplayText" is a string that will be bound to a TextBlock in the XAML view to display the size information for the Silverlight window.
  • The public method "WndSizeChanged" will be bound to the "SizeChanged" event of the Silverlight window in the XAML view. This method takes the window size information from the "SizeChangedEventArgs" input parameter and uses it to update the "DisplayText" property.
Now let us take a look at how the view model is bound to the XAML view.

The XAML View "MainPage.xaml"

The XAML view that the view model class "MainPageViewModel" is bound to is implemented in the "MainPage.xaml" file:
<UserControl x:Class="EventBindingExample.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"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    mc:Ignorable="d" FontFamily="Verdana" FontWeight="SemiBold">
 
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SizeChanged">
            <ei:CallMethodAction MethodName="WndSizeChanged"
                TargetObject="{Binding}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
 
    <Grid x:Name="LayoutRoot" Background="White"
          VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBlock Foreground="Green" Text="{Binding Path=DisplayText}" />
    </Grid>
</UserControl>
The "DisplayText" property of the view model class is bound to a TextBlock and the "WndSizeChanged" method in the view model is bound to the "SizeChanged" event of the Silverlight window. In order to make the event binding successful, the signature of the method in the view model needs to match exactly the signature required by the event handler delegate of the bounding event.
Now, we finish this demo Silverlight application. Is it so simple? Will the event binding work? Yes, it works. We can now run the application.

Run the Application

Set the "EventBindingExampleWeb" project as the start up project and set the "EventBindingExampleTestPage.aspx" page as the start page, we can debug run the Silverlight application. When the application starts, the "SizeChanged" event of the Silverlight window fires. This event triggers the method "WndSizeChanged" in the view model to update the "DisplayText" property, so the correct size of the window is displayed for you.
RunAppSmall.JPG If you change the size of the browser window, you can see that the displayed text is changed as you are changing the window size.
RunAppBig.JPG

Conclusion

This article demonstrated that we can bind events to the methods in the view models in Silverlight applications. In concluding this article, we will review the two important points when binding events to the methods in the view models in Silverlight applications.
  • To bind events to the view models in Silverlight applications, you need to use the functionalities provided by the "Microsoft Expression Blend SDK". In particular, you need to add references to the "Microsoft.Expression.Interactions.dll" and the "System.Windows.Interactivity.dll" in your project.
  • In order to make the event binding successful, the signature of the method in the view model needs to match exactly the signature required by the event handler delegate of the bounding event.

Points of Interest

  • This simple article introduced a method to bind events to the corresponding methods in the MVVM view models in Silverlight applications.
  • The method introduced in this article is simple. But it is significant in developing Silverlight MVVM applications because when combined with command binding, we can almost eliminate all the code-behind methods in the XAML views to better conform to the MVVM pattern.
  • According to Pete Brown, the method introduced in this article may be slightly slower than implementing the event handlers in the code-behind files of the XAML views, because this method uses reflection. The advantage of this method is that it applies to all the UI events fired from all the Silverlight components.
  • The method introduced here is largely from the book "Silverlight 4 in Action" by Pete Brown. If you are interested in Silverlight development, this book should be a good reference for you.
  • Once again, MVVM is a good pattern in developing Silverlight applications. But you still need to make your own judgment on a case by case basis. The best design pattern is the pattern that best fits your application's need, regardless if it is MVVM or not.
  • I hope you like my postings and I hope this article can help you in one way or the other.

History

This is the first revision of this article.

No hay comentarios:

Publicar un comentario