Click here to Skip to main content
Click here to Skip to main content

Using EventTrigger in XAML for MVVM – No Code Behind

, 6 Nov 2010
Rate this:
Please Sign up or sign in to vote.
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.

Introduction

I have seen people writing Code Behind a lot while they are working in the MVVM framework. 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 and remove the “MainPage.xaml” and its 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 creates 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 required 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 there are 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 an 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 its 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 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 that there is 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 popped-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 see 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.

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 feedback, suggestions here. If you have any questions, 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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

_ Kunal Chowdhury _
Technical Lead
India India
Kunal Chowdhury is a Microsoft "Client Development" MVP (Most Valuable Professional), a Codeproject Mentor, Telerik MVP, Nokia Developer Champion, Speaker in various Microsoft events, Author, passionate Blogger and a Software Engineer by profession.
 
He is currently working in an MNC located in India. He has a very good skill over XAML, C#, Silverlight, Windows Phone, WPF and Windows 8 (WinRT). He posts his findings, articles in his technical blog and CodeProject.
 
Technical Blog: http://www.kunal-chowdhury.com
Facebook: http://facebook.com/blog.kunal
Twitter : http://twitter.com/kunal2383
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
GeneralMy vote of 5 PinmemberMember 973830621-Feb-13 4:59 
QuestionMy vote of 5 PinmemberRajamohan Dhanushkodi31-Jan-13 5:30 
QuestionIs the source code available for the referenced dlls? PinmemberJohn Orendt28-Dec-12 21:56 
AnswerRe: Is the source code available for the referenced dlls? Pinmvp_ Kunal Chowdhury _31-Dec-12 17:58 
GeneralViewModal PinmemberRajibdotnet0520-May-11 15:48 
QuestionError - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmemberAfonso Gomes8-Apr-11 5:26 
AnswerRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmvpKunal_Chowdhury8-Apr-11 5:34 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmemberAfonso Gomes8-Apr-11 5:58 
The error persists.
 
I will give some details (hope it helps).
 
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<si:CallDataMethod Method="Btn_LoadPlant_Click"/>
</i:EventTrigger>
</i:Interaction.Triggers>
 
This is inside a Button that is inside a Grid that is inside an expander that is inside a border that is inside the layout root canvas. The canvas has a property DataContext to the viewModel that I want.
 
There are the definitions of the "i" and "si":
 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:si="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"
 
EDIT:
 
Also when I try to make something by '<si:(something)' nothing appears with the options as usual.
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmvpKunal_Chowdhury8-Apr-11 6:03 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmemberAfonso Gomes8-Apr-11 6:29 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmvpKunal_Chowdhury8-Apr-11 6:33 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmemberAfonso Gomes8-Apr-11 16:00 
AnswerRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmvpKunal_Chowdhury8-Apr-11 16:16 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmemberAfonso Gomes9-Apr-11 23:52 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' PinmvpKunal_Chowdhury10-Apr-11 1:29 
GeneralMy vote of 5 PinmemberProstoTelo28-Feb-11 5:52 
GeneralRe: My vote of 5 PinmvpKunal_Chowdhury28-Feb-11 6:00 
Generalawesome PinmemberProstoTelo28-Feb-11 5:50 
GeneralRe: awesome PinmvpKunal_Chowdhury28-Feb-11 5:59 
GeneralMy vote of 5 Pinmembertom-englert20-Nov-10 5:48 
GeneralRe: My vote of 5 PinmvpKunal_Chowdhury28-Feb-11 5:58 
GeneralExpression.Samples.Interactivity is Deprecated Pinmemberrsmackay15-Nov-10 12:40 
GeneralRe: Expression.Samples.Interactivity is Deprecated PinmentorKunalChowdhury17-Nov-10 21:24 
GeneralRe: Expression.Samples.Interactivity is Deprecated PinmemberJay R. Wren7-Feb-11 11:41 
GeneralDragndrop Pinmemberkoo98-Nov-10 11:48 
GeneralGood one PinmvpAbhishek Sur6-Nov-10 22:35 
GeneralRe: Good one PinmentorKunalChowdhury6-Nov-10 22:53 
GeneralMy vote of 5 Pinmemberdefwebserver6-Nov-10 4:08 
GeneralRe: My vote of 5 PinmentorKunalChowdhury6-Nov-10 4:23 
GeneralMy vote of 5 Pinmemberlinuxjr6-Nov-10 2:17 
GeneralRe: My vote of 5 PinmentorKunalChowdhury6-Nov-10 2:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140814.1 | Last Updated 6 Nov 2010
Article Copyright 2010 by _ Kunal Chowdhury _
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid