Click here to Skip to main content
15,867,834 members
Articles / Web Development

Using EventTrigger in XAML for MVVM – No Code Behind

Rate me:
Please Sign up or sign in to vote.
4.98/5 (28 votes)
6 Nov 2010CPOL8 min read 274.8K   7.4K   54   33
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:

C#
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:

XML
<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)


Written By
Technical Lead
India India

Kunal Chowdhury is a former Microsoft "Windows Platform Development" MVP (Most Valuable Professional, 2010 - 2018), a Codeproject Mentor, Speaker in various Microsoft events, Author, passionate Blogger and a Senior Technical Lead 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 app development. He posts his findings, articles, tutorials in his technical blog (www.kunal-chowdhury.com) and CodeProject.


Books authored:


Connect with Kunal on:





Comments and Discussions

 
QuestionPassing event parameters to the viewModel Pin
Member 1066774417-Apr-15 9:42
Member 1066774417-Apr-15 9:42 
Questiondamage files Pin
mostafa kandil16-Feb-15 1:17
mostafa kandil16-Feb-15 1:17 
GeneralMy vote of 5 Pin
Member 973830621-Feb-13 4:59
Member 973830621-Feb-13 4:59 
QuestionMy vote of 5 Pin
Rajamohan Dhanushkodi31-Jan-13 5:30
Rajamohan Dhanushkodi31-Jan-13 5:30 
QuestionIs the source code available for the referenced dlls? Pin
John Orendt28-Dec-12 21:56
John Orendt28-Dec-12 21:56 
AnswerRe: Is the source code available for the referenced dlls? Pin
Kunal Chowdhury «IN»31-Dec-12 17:58
professionalKunal Chowdhury «IN»31-Dec-12 17:58 
GeneralViewModal Pin
Rajibdotnet0520-May-11 15:48
Rajibdotnet0520-May-11 15:48 
QuestionError - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' Pin
Afonso Gomes8-Apr-11 5:26
Afonso 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' Pin
Kunal Chowdhury «IN»8-Apr-11 5:34
professionalKunal Chowdhury «IN»8-Apr-11 5:34 
Just do the following steps:

- Remove the assembly reference
- Clean the solution
- Add the assembly reference once again
- Rebuild the solution

It will work definitely. If then also you are getting error, close the Visual Studio and remove the obj, bin and ClientBin folder. Do the above steps once again. It will surely work.

It's an issue we face in Visual Studio sometimes and that's the step to resolve it. Let me know.

Regards - Kunal Chowdhury | Microsoft MVP (Silverlight) | CodeProject MVP | Software Engineer

My Latest Blog Feed [04-April-2011]:  A Complete Guide to Expression Blend 4 Shortcut Keys   [^Blog^]

Appreciate your vote and feedback

GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' Pin
Afonso Gomes8-Apr-11 5:58
Afonso Gomes8-Apr-11 5:58 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' Pin
Kunal Chowdhury «IN»8-Apr-11 6:03
professionalKunal Chowdhury «IN»8-Apr-11 6:03 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' Pin
Afonso Gomes8-Apr-11 6:29
Afonso 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' Pin
Kunal Chowdhury «IN»8-Apr-11 6:33
professionalKunal Chowdhury «IN»8-Apr-11 6:33 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' Pin
Afonso Gomes8-Apr-11 16:00
Afonso 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' Pin
Kunal Chowdhury «IN»8-Apr-11 16:16
professionalKunal Chowdhury «IN»8-Apr-11 16:16 
GeneralRe: Error - The tag 'CallDataMethod' does not exist in XML namespace 'clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity' Pin
Afonso Gomes9-Apr-11 23:52
Afonso 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' Pin
Kunal Chowdhury «IN»10-Apr-11 1:29
professionalKunal Chowdhury «IN»10-Apr-11 1:29 
GeneralMy vote of 5 Pin
ProstoTelo28-Feb-11 5:52
ProstoTelo28-Feb-11 5:52 
GeneralRe: My vote of 5 Pin
Kunal Chowdhury «IN»28-Feb-11 6:00
professionalKunal Chowdhury «IN»28-Feb-11 6:00 
Generalawesome Pin
ProstoTelo28-Feb-11 5:50
ProstoTelo28-Feb-11 5:50 
GeneralRe: awesome Pin
Kunal Chowdhury «IN»28-Feb-11 5:59
professionalKunal Chowdhury «IN»28-Feb-11 5:59 
GeneralMy vote of 5 Pin
tom-englert20-Nov-10 5:48
tom-englert20-Nov-10 5:48 
GeneralRe: My vote of 5 Pin
Kunal Chowdhury «IN»28-Feb-11 5:58
professionalKunal Chowdhury «IN»28-Feb-11 5:58 
GeneralExpression.Samples.Interactivity is Deprecated Pin
rsmackay15-Nov-10 12:40
rsmackay15-Nov-10 12:40 
GeneralRe: Expression.Samples.Interactivity is Deprecated Pin
Kunal Chowdhury «IN»17-Nov-10 21:24
professionalKunal Chowdhury «IN»17-Nov-10 21:24 

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

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