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:
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:
- “System.Windows.Interactivity.dll”
- “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.
Actually, the above step is not required if you copy the libraries to a proper location, so that your project can access them.
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.
Now, browse to the assembly folder where you kept your DLLs and add them to your project.
Click “Add” to continue.
You will see the assemblies added as reference to your project. Have a look into the following screenshot:
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.
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:
Once you added the xmlns
namespace, create a UserControl
.Resources tag as shown below and add the ViewModel
as Static Resource to the page.
Set the DataContext
of the LayoutRoot
Grid to the Static
Resource “mainViewModel
” which we added just now.
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:
Now add another namespace “Expression.Samples.Interactivity
” in the XAML page. Have a look into the picture:
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:
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.
Now set the method name to the method we have inside our ViewModel
i.e. “HandleShowMessage
”. You will have the following code now:
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!!!) 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.
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.
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:
What do you say, will it work if we run the application? Let’s see… 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.
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.
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:
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” . The background color has been changed without writing anything in the code behind!!!
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…