Introduction
MVVM is a pattern that is most famous known as Model View View Model Pattern. In this article we will see how we can implement MVVM pattern in a sample Silverlight Application.
Creating Silverlight Project
Fire up Visual Studio 2008 and create a Silverlight Application. Name it as SilverlightMVVMSample.
We will start with Model.
1) Add a folder to the Silverlight Project and name it as Model.
2) Add a class to it, name it as Question.cs.
Now here is the basic idea about our Sample application; we will have some questions and user has to type the answers in textbox. If it is true/false it will be notified.
So basically the Question class will implement INotifyPropertyChanged interface and we will have similar properties as shown in below code.
public class Question : INotifyPropertyChanged
{
public string Text { get; set; }
public string ActualAnswer { get; set; }
private string _provided;
public string ProvidedAnswer
{
get
{
return _provided;
}
set
{
_provided = value;
RaisePropertyChanged("ProvidedAnswer");
RaisePropertyChanged("Grade");
}
}
public bool Grade
{
get { return (ActualAnswer == _provided); }
set
{
RaisePropertyChanged("Grade");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged!=null)
{
this.PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
}
}
Now we have 4 properties such as Text, ActualAnswer, ProvidedAnswer and Grade. Here one thing you have noticed that whenever there is a change in property of ProvidedAnswer it implements the method RaisePropertyChanged. It's actually a customized method where we are checking with the PropertyChanged property. If it is not null, fire the event.
Now we will add ViewModel to the project.
3) Add a folder named ViewModel and add a class to it. Name it QuestionViewModel.cs.
Now ViewModel is the part where data comes, it can be any method from the WebService or any data. Here we will create our own data for our sample application.
Add a property of ObservableCollection of Question type. We will write a method which will create some data for us. The code looks like the following.
public class QuestionViewModel
{
public ObservableCollection<Question> Questions { get; set; }
public void FetchQuestions()
{
ObservableCollection<Question> q = new ObservableCollection<Question>();
q.Add(new Question() {Text="What is 2 + 2 ?", ActualAnswer="4" });
q.Add(new Question() { Text = "What is 9 - 2 ?", ActualAnswer = "7" });
Questions = q;
}
}
Finally at the end of the method FetchQuestions we have assigned the added values to the collection.
Now the View part, we will add a UserControl to the project and design our application.
4) Create a folder called View and add a UserControl to it. Name it as QuestionView.
Now go ahead and look into the Xaml view. You can see the Grid; now it's time to show your Blend 3 skills and design as per required. Add the following:
- TextBlock (Displaying the Question)
- TextBox (User Input as Answer)
- CheckBox (Correct/Incorrect)
The following Xaml will help you building a good design.
<Grid x:Name="LayoutRoot" Background="LightBlue">
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="300" Height="32">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="QuestionText" HorizontalAlignment="Stretch" Text="{Binding Path=Text}" Grid.Column="0"/>
<TextBox x:Name="QuestionAnswered" Text="{Binding Path=ProvidedAnswer, Mode=TwoWay}" Width="20" HorizontalAlignment="Right" Grid.Column="1"/>
<CheckBox x:Name="GradeCheck" IsChecked="{Binding Path=Grade}" Grid.Column="2" IsEnabled="False"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
Now one of the important tasks is pending. We have created our own view, our own model and view model but we haven't registered the view with our MainPage view.
So we will do it now.
5) Open MainPage.xaml
6) Add the Namespace of View Folder by typing as follows:
xmlns:views="clr-namespace:SilverlightMVVMSample.View"
7) Now add QuestionView to the Grid
The XAML will look as following:
<Grid x:Name="LayoutRoot">
<views:QuestionView x:Name="QuestionDataView"/>
</Grid>
Now that you have added the QuestionView to the MainPage (MainView); we have yet to initialize the ViewModel.
8) Add a Loaded event to the MainPage constructor.
Loaded += new RoutedEventHandler(MainPage_Loaded);
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
QuestionViewModel qData = new QuestionViewModel();
qData.FetchQuestions();
QuestionDataView.DataContext = qData.Questions;
}
As you can see we have initialized the QuestionViewModel and called the method FetchQuestions(). As you remember in FetchQuestions() method we initialized our data. And finally the views DataContext is the Questions property.
As this is done now you can run your application. Press F5 to run your application.
As you run your application when you enter the answer into the respective textboxes the checkbox IsChecked property is changing.
So this is it. This was our sample application of implementing MVVM pattern in Silverlight 3. We will do something more interesting in my coming up articles. Enjoy Coding.