Using EventTrigger in XAML for MVVM – No Code Behind Code



image

I have seen people writing Code Behind a lot while they are working in the MVVM framework. A huge lines of code in their xaml.cs file actually creates problem to the designers to change anything present in the XAML. Why is this so? Because, lots of people don’t know how to use Triggers to call the MVVM methods to complete their business need.

 

Michael Washington has a nice article on DataTrigger to reduce the Code behind file. It definitely reduces the problem of MVVM that world faces generally. Also, we need to do some additional things to reduce the code behind.

 

In this article, I will show you how to fire Triggers to call some methods present in your ViewModel, instead of writing in the code behind file. Read more to learn about it.

 

Setting up the MVVM project

First we need to setup the MVVM project. Create a Silverlight project & remove the “MainPage.xaml” and it’s code behind from the solution. Now create the MVVM folder structure called “Models”, “Views” and “ViewModels” in your project. Create a new XAML page called “MainView” inside the Views folder. This also create the respective code behind file (“MainView.xaml.cs”) for you in the same folder. Now create the ViewModel called “MainViewModel” inside the ViewModels folder.

 

Have a look into the MVVM folder structure for our project here:

 

image

 

Make sure to change the RootVisual from MainPage to MainView in your App.xaml.cs file. Build the project to ensure that there are no errors. If you face any issues, fix them right now.

 

 

Adding External Libraries

Now you need 2 dll assemblies to use the EventTrigger for our case and they are as below:

  1. “System.Windows.Interactivity.dll”
  2. “Expression.Samples.Interactivity.dll”

Download the libraries from the attached zip file and extract them to your local drive. In our case, we are going to put them inside the solution. Copy the libraries to a folder called “ExternalAssemblies” and make sure to exclude the folder from the project.

 

image

 

Actually, the above step is not require if you copy the libraries to a proper location, so that your project can access them.

 

image

 

Now right click on the project or the reference folder. A context menu will popup as shown below. Click “Add Reference” to show the Add reference dialog.

 

image

 

Now, browse to the assembly folder where you kept your dlls and add them to your project.

 

image

 

Click “Add” to continue.

 

image

 

You will see the assemblies added as reference to your project. Have a look into the following screenshot:

 

image

 

Build the solution once again to check if any build errors and resolve them as necessary.

 

 

Create the Basic View and ViewModel

Let us modify the View with some simple controls inside it. Let’s add one TextBox, where we can insert Employee name and one button which will have a click event to show some message. Don’t add any click event there right now. We will add them later.

 

image

 

Once your above view is ready, jump into the ViewModel to add some properties. Let’s add a EmployeeName of type string. Add one simple method to show a MessageBox with some text.

 

Here is our sample ViewModel:

 
using System.Windows;
 
namespace MVVMEventTriggerDemo.ViewModels
{
    public class MainViewModel
    {
        public string EmployeeName { get; set; }
        public string Country { get; set; }
 
        public void HandleShowMessage()
        {
            MessageBox.Show("Hello " +EmployeeName+ ", Welcome to EventTrigger for MVVM");
        }
    }
}

 

Once your View & ViewModel is ready, build & run the application to see the UI that we are going to demonstrate.

 

 

Binding ViewModel to the View

As our ViewModel is ready, it’s time for us to bind the ViewModel with the View. Remember that, your View knows what is it’s ViewModel but not the reverse. Your ViewModel should not have any reference to the view.

 

Let us add the ViewModel for the View. Open your MainView.xaml page. In the usercontrol tag add the xmlns namespace for the ViewModel as shown in the below figure:

 

image

 

Once you added the xmlns namespace, create a UserControl.Resources tag as shown below and add the ViewModel as Static Resource to the page.

 

image

 

Set the DataContext of the LayoutRoot Grid to the Static Resource “mainViewModel” which we added just now.

 

image

 

Now Bind the ViewModel property named “EmployeeName” to the TextBox and set the Mode as “TwoWay”, so that, if end user changes the text of the TextBox it will automatically update the property present in the ViewModel.

 

 

Setting up Triggers

It’s time for us to set the Trigger to our XAML for the button. Add the xmlns namespace for both the assemblies. First add the namespace for “System.Windows.Interactivity” as shown in the below screenshot:

 

image

 

Now add the another namespace “Expression.Samples.Interactivity” in the XAML page. Have a look into the picture:

 

image

 

As our xmlns namespaces are imported successfully, we will now add the Trigger to the button. Modify the button tag so that, it will now coded as a Container. Inside the tag, add the Interaction.Triggers tag as shown below:

 

image

 

Add the EventTrigger from the Interactivity namespace and set the EventName to “Click”. If you want to use a different event, you can modify it respectively.

 

Import the Samples Interaction inside the Event Trigger and you will see, there are plenty of methods available to do several operations inside the XAML itself. You can call DataMethod inside a ViewModel, you can change the state of the FrameworkElement to another valid state, you can invoke DataCommand, pause media, Show Message etc.

 

Let us do some of them, so that, you can understand the feature easily. First add a CallDataMethod event.

 

image

 

Now set the Method name to the method we have inside our ViewModel i.e. “HandleShowMessage”. You will have the following code now:

 

image

 

Later, I will share the whole code for you to copy. Also, the whole solution is attached for you to download. Ok, come into the actual topic. Open your code behind file. There you will see the file is totally empty. Confused smile (confused!!!) Yes, it is totally empty. It has only the constructor and a call to InitializeComponent() method, which is always necessary for any Silverlight page. Hence, we can consider it as empty class. You will see there are no extra code written to raise and implement the Button Click event.

 

image

 

A very neat & clean code behind file, right? Now build the solution and run the application by pressing F5. You will see the application loaded inside the browser window. Enter a name inside the TextBox and click on the button “Show Message”. OMG!!! The button is firing the event to the ViewModel and the MessageBox has been pop-up into the screen with the entered text which was binded to the EmployeeName property.

 

image

 

Let us modify the XAML a little bit and add the ShowMessageBox interation event to the Trigger with proper Caption, Message and MessageBoxButton. See the code in the following figure:

 

image

 

What do you say, will it work if we run the application? Let’s see… Open-mouthed smile  Run the application once again now. You will the same application loaded into the screen. Enter a name in the TextBox and click “Show Message” button. You will see the following message box pop up to the screen as shown earlier.

 

image

 

Click “OK”. Woo, another message box!!! Yes, this is the message box that we added just now in the xaml page with the exact caption and message string. The message box is not present in our code behind nor in the viewmodel. It is the default one provided by the library with customized text.

 

image

 

So, what do you think? We can only call a data method for MVVM using EventTrigger!!! If we want to change some property of the UI Element, how can we do that? In such case, do we have to write inside the CodeBehind or do we have to create a property inside view model and bind it to the UI?

 

No, don’t worry. You don’t have to do anything for that. You have to just call the SetProperty from the sample interation library with proper parameters. Have a look into the code:

 

image

 

Here, I set the TargetName to LayoutRoot i.e. the Main Grid. We want to change the Background color of the Grid from White to PaleGoldenrod. Hence set the value for it.

 

Now, run the application once again and click “Show Message”. You will see the message in the screen. Click “OK” Surprised smile. The background color has been changed without writing anything in the code behind!!!

 

image

 

So simple right? Then why are you writing code in the xaml.cs file? Stop it immediately and move into the proper MVVM pattern.

 

Here is the whole XAML code for your reference:

 
<UserControl x:Class="MVVMEventTriggerDemo.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:MVVMEventTriggerDemo.ViewModels"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:si="clr-namespace:Expression.Samples.Interactivity;
                                            assembly=Expression.Samples.Interactivity"
Height="132" Width="250">
<UserControl.Resources>
        <viewModel:MainViewModel x:Key="mainViewModel"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" 
                              DataContext="{StaticResource mainViewModel}">
        <TextBox Text="{Binding EmployeeName, Mode=TwoWay}" 
                 Width="200" Height="30" Margin="28,24,22,78" />
        <Button Content="Show Message" Width="100" Height="25" Margin="128,70,22,37">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <si:CallDataMethod Method="HandleShowMessage"/>
                    <si:ShowMessageBox Caption="Thank you"
                                       Message="Thanks for trying the Example"
                                       MessageBoxButton="OK"/>
                    <si:SetProperty TargetName="LayoutRoot" 
                                    PropertyName="Background" 
                                    Value="PaleGoldenrod"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

 

The whole solution is also available as a downloadable zip file.

 

 

Download

You can download the source code of the article from here:

Please let me know, if you have any issue accessing the above links.

 

 

End Note

Try it on your end and create some samples by yourself. After doing this, you will be familiar with the MVVM pattern and then stop writing code inside your xaml.cs file. Move all to ViewModel and use the properties to bind the data to the view. Call the viewmodel method right from the xaml and also raise necessary events from the view.

 

Hope, this will help you to understand the event triggering in MVVM way. Please don’t stop to share your feedbacks, suggestions here. If you have any question, let me know. I will try to answer you as soon as possible.

 

Also, read the article shared by Michael Washington. That will clear the concept about data trigger to you. Enjoy working with MVVM now. All the best… Thumbs up

10 comments

  1. Good article, Thanks! But I prefer use construction like this:

    ReplyDelete
  2. Hey Kunal, Nice article. I see you are using the MVVM pattern. Have you looked at the MVVM Light toolkit. It gives you a lot more flexibility in terms of messaging and event triggering.

    ReplyDelete
  3. Great article,
    I'm just confused why the ViewModel has no INotifyPropertyChanged interface implemented?

    ReplyDelete
  4. @Drazen: Not require all the cases... :)

    ReplyDelete
  5. Simplicity in sentences, description of each steps(even addition of references), clear cut approach and upto the mark, thats why i love to read your blogs and other silverlight related articles, you are a genius you taught me silverlight without any external help, eagerly waiting for your next tutorial series on silverlight after tutorial 4 controls in silverlight.
    Thanks for sharing k/w in easy way.
    Rafat

    ReplyDelete
  6. Hi Kunal,
    knowledgeable tutorial. I downloaded it and using the dll into my another project but it gives me dll error. both dll which you have provided is in v2.0
    but i am using silverlight 5. so I couldnt add it and execute it.

    what should i do?
    because i couldnt find that dll to download

    ReplyDelete
  7. Hi Rohi,

    If you are using Silverlight 5, just download and install the latest Expression Blend 5 (trial is also fine). This will install the latest dlls.

    ReplyDelete
  8. Hey Hi again,

    as per your suggestion i tried by downloading blend 5 sdk. but i couldnt found Expression.Samples.Interactivity.dll in it. So I just checked with system.windows.interactivity.dll but it throws me error The attachable property 'Triggers' was not found in type 'Interaction'" .
    plz help me out.
    I want to navigate user to another page after login.
    how to do it???

    ReplyDelete
  9. Hi Rohi,

    I will check it out and let you know soon.

    ReplyDelete
  10. hi..
    I tried this, Works fine!
    But I want to know why this same thing doesn't work while Text Box is in the Data Grid's Template... ?
    With only Text box - It is OK.
    But with text- box in Data-grid --No notification

    I'm trying to do same but my text-box is in the data-grid's template.
    It doesn't notify on text-changed.

    ReplyDelete


 
© 2008-2014 Kunal-Chowdhury.com | Designed by Kunal Chowdhury
Back to top