Using Model-View-ViewModel Pattern in Your Windows Phone Application

Introduction

Wikipedia describes Model-View-ViewModel
as an architectural pattern, which is based on the Model View Controller
Pattern. It was originated at Microsoft. The principal behind MVVM is that a
user interface designer might have requirements that are different from a
traditional developer who would focus more on the business logic of the
application.

The MVVM pattern is a
specialization of the Presentation Model
design pattern
, which was introduced by Martin Fowler.

Elements of MVVM

The MVVM pattern seeks to build
upon the advantages XAML
offers by using XAML to validate the data and push the binding to the model.
The elements of MVVM design pattern include:

  • Model – Similar to the MVC
    pattern, the model represents the data layer.
  • View – The view represents
    the UI layer which is displayed to the user in the form of buttons, windows,
    graphics, etc.
  • ViewModel – This layer can
    be viewed as abstraction of the view. It also helps in data binding between the
    Model and the View. The ViewModel passes in commands from View
    into the Model.

To leverage MVVM in your Windows Phone
application, you need to make sure that the user interface has to be a XAML
control.

Hands-On

To get started, create a Windows
Phone application by selecting “Windows Phone application” project type from
templates under “Silverlight
for Windows Phone” in Visual
Studio
. Let us call it MVVMDemo.

Our MVVMDemo project will use the
MVVM design pattern to show information about tourists.

Begin by creating folders in your
Visual Studio project called “Model”, “View” and “View Model”.

Create a class inside Model
folder called TouristModel.cs.

Add the following properties in
the TouristModel class : Name, Address, ZipCode, EmailAddress. Also provide a
constructor that takes in the values for these properties and assigns the
values.

The code of TouristModel class
will look as follows:

public class TouristModel
    {
        public string Name
        {
            get;
            set;
        }
        public string Address
        {
            get;
            set;
        }
        public string ZipCode
        {
            get;
            set;
        }
        public string EmailAddress
        {
            get;
            set;
        }
        public TouristModel(string name, string address, string zip, string email)
        {
            this.Name = name;
            this.Address = address;
            this.ZipCode = zip;
            this.EmailAddress = email;
        }
    }

Now, let us go ahead and design
the ViewModel class. Add a class inside the ViewModel folder called
TouristViewModel.cs

This is the class representing
the view model. This class will implement ObservableCollection of type Touristmodel.
Let’s add a default constructor, which will add a few tourists.

The code for TouristViewModel
class will look as follows.

public class TouristViewModel : ObservableCollection<TouristModel>
    {
        public TouristViewModel()
        {
            this.Add(new TouristModel("Curious George", "MonkeyLand", "90210", "george@monkey.com"));
            this.Add(new TouristModel("Thomas The Tank Engine", "TrainLand", "20910", "thomas@trainstation.com"));
            this.Add(new TouristModel("Fred Flinstone", "DinosaurLand", "81234", "fred@stoneage.com"));
        }
    }

Now, go ahead and add a Windows
Phone user control under the View folder called TouristView.xaml.

In this user control, we will
present names of our tourists in a list view. When the user clicks on a
tourist, we will render the details of the selected tourist in another control
(using another view).

To start with, edit the XAML of
the Grid control to as under.

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="150"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <src:TouristViewModel x:Key="Tourists"/>
        </Grid.Resources>
        <TextBlock Text="Tourists" FontSize="24" FontWeight="Bold" Grid.Row="0" Foreground="white" 
                   Margin="5,5,0,10"></TextBlock>
        <ListBox Name="TouristList" Grid.Row="1" ItemsSource="{StaticResource Tourists}" 
                 SelectionChanged="TouristList_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock 
                        Text="{Binding Name}" FontSize="24" />

                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <detailview:TouristDetailsView x:Name="Touristdetails" Grid.Row="2"
                                Visibility="Collapsed"></detailview:TouristDetailsView>
    </Grid>

Here is what the XAML above does:


  • Specifies “Tourists” as a resource for the Grid. The highlighted portion
    in the XAML shows that for the TouristList, we are using “Tourists” as a data
    source.
  • We have a ListBox called TouristList. When a user selects a tourist from
    the list, we will fire up the TouristList_SelectionChanged event.
  • We also have a TouristDetailsVIew control on the page, which initially
    is in a collapsed state. We will discuss more about this control in the next
    section.

Right click on TouristList_SelectionChanged method to go to the event handler. If you do not have this created, it will
create one.

In this event handler, add code
to get the details of the selected tourist and render it using the
TouristDetailsView control.

        private void TouristList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            TouristModel details = (TouristModel)TouristList.SelectedItem;
            Touristdetails.DataContext = details;
            Touristdetails.Visibility = Visibility.Visible;
        }

Now, we will create the
TouristDetailsView user control.

Add another user control under
the View folder and name it TouristDetailsView.

In the XAML, add code to show the
properties of the tourist using appropriate controls as shown below.

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="40*"></RowDefinition>
            <RowDefinition Height="100"></RowDefinition>
            <RowDefinition Height="231*"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="TOURIST DETAILS" HorizontalAlignment="Center" FontSize="24" FontWeight="Bold" ></TextBlock>
 
        <StackPanel Orientation="Vertical" Background="Transparent" Grid.Row="2" >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name"  Width="110"  FontSize="22" TextWrapping="Wrap" Margin="5,8"
                       Foreground="#FFFFBEBE"></TextBlock>
                <TextBlock Text="{Binding Name}"   FontSize="22" Foreground="White" Margin="13"
                       TextWrapping="Wrap" FontWeight="Bold"></TextBlock>
            </StackPanel>
 
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Address"  Width="110"  Foreground="#FFFFBEBE"  Margin="5,12" FontSize="22" 
                       TextWrapping="Wrap" ></TextBlock>
                <TextBlock Text="{Binding Address}"   FontSize="22" Foreground="White" Margin="13" TextWrapping="Wrap" 
                       FontWeight="Bold"></TextBlock>
            </StackPanel>
 
            <StackPanel Orientation="Horizontal">
                <TextBlock  Text="ZipCode"  Width="110"  Foreground="#FFFFBEBE" FontSize="22"  Margin="5,14" 
                        TextWrapping="Wrap" ></TextBlock>
                <TextBlock Text="{Binding ZipCode}" FontSize="22" Foreground="White" Height="Auto" Margin="13" 
                       TextWrapping="Wrap" FontWeight="Bold"></TextBlock>
            </StackPanel>
 
            <StackPanel Orientation="Horizontal">
                <TextBlock Width="110"  Text="Email"   Foreground="#FFFFBEBE" FontSize="22" Margin="5,16" 
                       TextWrapping="Wrap" ></TextBlock>
                <TextBlock Text="{Binding EmailAddress}"   FontSize="22"  Height="Auto" Foreground="White" Margin="13" 
                           TextWrapping="Wrap"   FontWeight="Bold"></TextBlock>
            </StackPanel>
 
            <Button Content="Close" Name="ButtonClose" Width="150" Height="60" Click="ButtonClose_Click" FontSize="20" 
                Foreground="#FFFFC4C4"></Button>
        </StackPanel>
    </Grid>

As we can see in the XAML above,
we use TextBlocks, which are data bound to different properties of the
TouristModel class.

We also added a button whose
purpose will be to close the details page.

The code for the Click event for
the Button is as follows.

        private void ButtonClose_Click(object sender, RoutedEventArgs e)
        {
            Visibility = Visibility.Collapsed;
        }

Now, we edit the XAML for
Mainpage to show the TouristVIew control and bind it to our data source.

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <view:TouristView x:Name="Tourists" DataContext="{Binding Path=TouristView}">
        </view:TouristView >
    </Grid>

Now, we have finished coding our
application. Run the application and you will the screen below.

Run the application
Figure 1: Run the application

If we double click on any name,
we will see the MVVM pattern in action, which will display the details of the
selected tourist on the page.

The MVVM pattern
Figure 2: The MVVM pattern

If we click Close, the details
will disappear from the page.

If you are having trouble
following along, you can checked out the sample code for this article where we
have this all coded up.

Summary

In this article, we learned about
the Model View View Model design pattern and also saw a Windows Phone
application using it for displaying content. I hope you have found this
information useful.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read