Introduction
Silverlight 4.0 and MVVM Pattern
What is MVVM Pattern:
MVVM (Model- View – View Model) is the WPF / Silverlight UI design Pattern code model. A certain guideline a developer should follows in order to achieve a more testable, debug gable, manageable, readable Application.
A zero code behind, yes no button click event hander in the code behind file, no form / windows load logic, no UI binding logic, No UI validation or type casting code in the code behind file. Yes i mean no code or logic in the mainpage.xaml.cs file.
So that one can write a unit test against the code behind file and instantiate it.
Following features are used in order to achieve the MVVM pattern with no logic on the UI code behind file , and to make sure that the presentation layer and logic are loosely couple.
1) Strong Two way binding capability of WPF/Silverlight UI (XAML)
2) IValueConvert for binding (eg: convert the string with colour class)
3) INotification or Dependency Property
4) Data context
5) Static resources
6) Icommand for avoiding the code behind event handler.
7) Use of validation=true in xaml(presentation layer)
In this example i have not use the IValueConvertor feature
Background
Before MVVM, the MVP pattern was famous for winform and wpf applications (Though it never took the full advantage of the Two way binding features of WPF). MVC pattern is still famous with Asp.net Application.
Draw back of the old fashion winform or wpf / Silverlight application (with no mvvm pattern)
1) The Presentation and the code behind logic are tightly coupled
2) If we change the UI control we have change the respective logic in the code behind
3) Cannot imagine of more than one view sharing the same logic.
4) Not possible to write a unit test for a code behind, as the presentation layer is tightly couple to the controls.
5) In normal WPF application the view (xaml) is treated just as a data storage.
Advantages of MVVM pattern:
1) Proper layering of the view and the data. The data is not stored in view, View is just for presenting the data.
2) Clean testable and manageable code.
3) No code behind so the Presentation layer and the logic are loosely coupled.
4) With Silverlight 4.0 we have a new ICommand Support
Using the code
In this example we have person name and age getting displayed on the text box and with click on a button the age will go up by a year till 26 and after that the button will get disable.. all this without code behind logic...
Step 1: Create a Silverlight Application in Viual studio 2010 and name it as “simplePersonandageMVVM”
Step 2: Once created add a class file and call it as “PersonModel.cs” and paste this code . (this would be the model thats is data object)
using System.ComponentModel;
namespace simplePersonandageMVVM
{
public class PersonModel : INotifyPropertyChanged
{
string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
fire("Name");
}
}
int age;
public int Age
{
get { return this.age; }
set
{
this.age = value;
fire("Age");
}
}
public PersonModel() { }
public PersonModel(string name, int age)
{
this.name = name;
this.age = age;
}
public void fire(string x)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(x));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
Step 3: Create another class call it as “PersonViewModel.cs” This would be the viewModel and will take the role of an adapter between view(presentation layer) and the Model(entity class).
namespace simplePersonandageMVVM
{
public class PersonViewModel
{
public PersonModel p { get; set; }
public PersonViewModel()
{
p = new PersonModel("prabjot", 20);
}
public ICommand GetPerson
{
get { return new GetPersonCommand(this); }
}
public void Increaseage(PersonModel d)
{
d.Age++;
string x = d.Age.ToString();
MessageBox.Show(x);
}
}
}
Step 4: Create a Command object class implementing the ICOMMAND interface and call it as “GetPersonCommand.cs”. This class overrides both the Icommand methods. Here the method CanExecute() checks for the condition if its met then only the button click is enable. Where as the other method Execute() takes care of execution action, on button click.
namespace simplePersonandageMVVM
{
public class GetPersonCommand : ICommand
{
PersonViewModel pincommand;
public GetPersonCommand( PersonViewModel Pcame)
{
pincommand= Pcame;
}
public bool CanExecute(object parameter)
{
if(pincommand.p.Age > 25)
{
return false ;
}
else
{
return true;
}
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
pincommand.Increaseage(pincommand.p);
}
}
}
Step 5: Finally your xaml file looks like this
<UserControl x:Class="simplePersonandageMVVM.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:local="clr-namespace:simplePersonandageMVVM"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<local:PersonViewModel x:Key="pkey" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White"
DataContext="{Binding Source={StaticResource pkey}}" >
<Grid Name="hi" DataContext="{Binding Path=p, Mode=TwoWay}">
<TextBox Height="23" HorizontalAlignment="Left" Margin="53,30,0,0"
Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=Name, Mode=TwoWay}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="53,68,0,0" Name="textBox2"
Text="{Binding Path=Age, Mode=TwoWay}" VerticalAlignment="Top" Width="120" />
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="53,112,0,0" Name="button1"
VerticalAlignment="Top" Width="75" Command="{Binding Path=DataContext.GetPerson, ElementName= LayoutRoot }"
CommandParameter="{Binding Path=Age, ElementName=hi}" />
</Grid>
</Grid>
</UserControl>
Download the code of this solution
Download simplePersonandageMVVM_-_Copy.zip - 2.27 MB
Please note the videos series on Silverlight including video for this example with explanation on command pattern plus other MVVM pattern examples with Data base and on wcf and linq with entity , is available on www.elearningfromhome.com