Visual Basic Windows Phone 7 Series #4. How to implement a model-view-viewmodel pattern in a Windows Phone application

Avatar

In our last post, I explained how to create a custom indeterminate progress bar application for Windows Phone 7. In this blog, I want to share a sample that will help you to implement a model-view-viewmodel pattern in a Windows Phone application. A model-view-viewmodel pattern is used to separate data from the user interface. This pattern allows the developers to code data models and the designers to create user interfaces. In this sample, I will demonstrate how to create a game tracker application by implementing the model-view-viewmodel pattern.

I will now demonstrate how easy it is to implement the model-view-viewmodel pattern in a Windows Phone application, using Visual Basic for Windows Phone Developer Tools. The model-view-viewmodel pattern can be implemented in 8 simple steps as follows:

  1. Create a sample application
  2. Create a data model, a viewmodel, and two views
  3. Create the main application page
  4. Maintain the page state
  5. Save the data to isolated storage
  6. Add the application bar
  7. Build and debug the application
  8. Rebuild in the release mode before publishing

Prerequisites:

            To implement the model-view-viewmodel pattern in a Windows Phone application, let’s follow the 8 simple steps mentioned earlier:

            Step 1 – Create a sample application

            1. Create a new project and browse to the “Silverlight for Windows Phone” node.
            2. Select the “Windows Phone Application” template.
            3. Enter a name for the application.
            4. Click OK. The MainPage.xaml page is displayed.

            Step 2 – Create a data model, a viewmodel, and two views

            Create a data model

            1. In Solution Explorer, right-click the application name and add a new folder.
            2. Rename the new folder as “Model”.
            3. Right-click the Model folder, and then add a class. The Add New Item dialog box is displayed.
            4. Enter the name for the class as “Accomplishment.vb”, and then click Add. The Accomplishment.vb page is displayed.
            5. Replace the code with the following code:

            Create a viewmodel

            In Solution Explorer, right-click the application name, and then add a new folder.

            1. Rename the new folder as “ViewModel”.
            2. Right-click the ViewModel folder, and then add a class. The Add New Item dialog box is displayed.
            3. Enter the name for the class as “ViewModel.vb”, and then click Add. The ViewModel.vb page is displayed.
            4. Replace the code with the following code:

            Create the first view

            1. In Solution Explorer, right-click the application name, and then add a new folder.
            2. Rename the new folder as “View”.
            3. Right-click the View folder, and then add a new item. The Add New Item dialog box is displayed.
            4. Select the “Silverlight for Windows Phone” node, and then select the “Windows Phone User Control” template.
            5. Enter the name for the view as “ItemView.xaml”, and then click Add. The ItemView.xaml page is displayed.
            6. In the <Grid> tag, add the following XAML code:

            Create the second view

            1. In Solution Explorer, right-click the View folder, and then add a new item. The Add New Item dialog box is displayed.
            2. Select the “Silverlight for Windows Phone” node, and then select the “Windows Phone User Control” template.
            3. Enter the name for the view as “LevelView.xaml”, and then click Add. The LevelView.xaml page is displayed.

            Create the custom data binding converter

            Open the LevelView.xaml.vb page, and replace the code with the following code:
             

             

            Create the user interface for the second view

            1. Open the LevelView.xaml page.
            2. In the <UserControl> tag, add the following XAML code:

            3. After the <UserControl> tag, add the following XAML code:

            4. In the <Grid> tag, add the following XAML code:

              <ListBox ItemsSource=”{Binding}”>

                   <ListBox.ItemTemplate>

                         <DataTemplate>

                             <Grid>

                                <Grid.ColumnDefinitions>

                                     <ColumnDefinition Width=”200″/>

                                     <ColumnDefinition Width=”80″/>

                                     <ColumnDefinition Width=”100″/>

                                </Grid.ColumnDefinitions>

                                <TextBlock x:Name=”Level” Text=”{Binding Path=Name, Mode=OneWay}” Grid.Column=”0″ HorizontalAlignment=”Left” VerticalAlignment=”Center”/>

                                <CheckBox x:Name=”Completed” IsChecked=”{Binding Path=Completed, Mode=TwoWay}” Grid.Column=”1″ HorizontalAlignment=”Center” IsEnabled=”{Binding Path=Completed, Converter={StaticResource BoolOpposite}}”/>

                                <TextBlock x:Name=”Check” Text=”{Binding Path=Completed, Mode=OneWay}” Grid.Column=”2″ HorizontalAlignment=”Center” VerticalAlignment=”Center”/>

                             </Grid>

                         </DataTemplate>

                   </ListBox.ItemTemplate>

              </ListBox>

            Step 3 – Create the main application page

            Create the user interface for the main application page

            1. Open the MainPage.xaml page.
            2. Click the MY APPLICATION text. In the Properties window, change the text property to “MVVM Test App”.
            3. Click the page name text. In the Properties window, change the text property to “game tracker”.
            4. In the <phone> tag, add the following XAML code:

              xmlns:views=”clr-namespace:MVVMTestApp”

            5. Replace the <Grid> tag for the content panel with the following XAML code:

              <!–ContentPanel – place additional content here–>

              <Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>

                  <StackPanel>

                      <TextBlock Text=”Items Collected” Foreground=”{StaticResource PhoneAccentBrush}” Style=”{StaticResource PhoneTextLargeStyle}” />

                      <views:ItemView x:Name=”ItemViewOnPage” Height=”200″/>

                      <TextBlock Text=”Levels Completed” Foreground=”{StaticResource PhoneAccentBrush}” Style=”{StaticResource PhoneTextLargeStyle}” />

                      <views:LevelView x:Name=”LevelViewOnPage” Height=”200″/>

                  </StackPanel>

              </Grid>

            Add the code for the main application page

            Open the MainPage.xaml.vb page, and replace the code with the following code:

            Partial Public Class MainPage

                Inherits PhoneApplicationPage

                Private vm As ViewModel

             

                ‘ Constructor

                Public Sub New()

                    InitializeComponent()

                    vm = New ViewModel

                End Sub

             

                Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)

                    MyBase.OnNavigatedTo(e)

             

                    ‘ Later, you will replace this line with something better

                        vm.GetAccomplishments()

                   

                    ‘ There are two different views, but only one view model.

                    ‘ So, use LINQ queries to populate the views.

             

                    ‘ Set the data context for the Item view.

                    ItemViewOnPage.DataContext = From Accomplishment In vm.Accomplishments

                                                 Where Accomplishment.Type = “Item”

                                                 Select Accomplishment

             

                    ‘ Set the data context for the Level view.

                    LevelViewOnPage.DataContext = From Accomplishment In vm.Accomplishments

                                                  Where Accomplishment.Type = “Level”

                                                  Select Accomplishment

             

                    ‘ If there is only one view, you could use the following code

                    ‘ to populate the view.

                    ‘ AccomplishmentViewOnPage.DataContext = vm.Accomplishments

                End Sub

             

            Step 4 – Maintain the page state

            1. In Solution Explorer, right-click the application name, and then add a class. The Add New Item dialog box is displayed.
            2. Enter the name for the class as “StateUtilities.vb”, and then click Add. The StateUtilities.vb page is displayed.
            3. Replace the code with the following code:

              Public NotInheritable Class StateUtilities

                  Private Shared _isLaunching As Boolean

               

                  Private Sub New()

                  End Sub

               

                  Public Shared Property IsLaunching As Boolean

                      Get

                          Return _isLaunching

                      End Get

                      Set(ByVal value As Boolean)

                          _isLaunching = value

                      End Set

                  End Property

              End Class

            4. Open the App.xaml.vb page.
            5. Replace the Application_Launching method with the following code:

              Private Sub Application_Launching(ByVal sender As Object, ByVal e As LaunchingEventArgs)

                      StateUtilities.IsLaunching = True

              End Sub

            6. Replace the Application_Activated method with the following code:

              Private Sub Application_Activated(ByVal sender As Object, ByVal e As ActivatedEventArgs)

                      StateUtilities.IsLaunching = False

              End Sub

            7. Open the MainPage.xaml.vb, and locate the following code:

              ‘ Later, you will replace this line with something better

                          vm.GetAccomplishments()

            8. Replace the code given in step 7 with the following code:

              ‘ Old instance of the application

              ‘ The user started the application from the Back button.

                  If (Not StateUtilities.IsLaunching) AndAlso Me.State.ContainsKey(“Accomplishments”) Then

                      vm = CType(Me.State(“Accomplishments”), ViewModel)

                      ‘MessageBox.Show(“Got data from state”)

                      ‘ New instance of the application

                      ‘ The user started the application from the application list,

                      ‘ or there is no saved state available.

                  Else

                      vm.GetAccomplishments()

                      ‘MessageBox.Show(“Did not get data from state”)

                  End If

            9. After the OnNavigatedTo method, add the following code:

              Protected Overrides Sub OnNavigatedFrom(ByVal e As System.Windows.Navigation.NavigationEventArgs)

                   MyBase.OnNavigatedFrom(e)

               

                   If Me.State.ContainsKey(“Accomplishments”) Then

                        Me.State(“Accomplishments”) = vm

                   Else

                        Me.State.Add(“Accomplishments”, vm)

                   End If

               

                   StateUtilities.IsLaunching = False

              End Sub

            Step 5 – Save data to isolated storage

            Open the ViewModel.vb page, and add the following code:

            Public Sub SaveAccomplishments()

               Dim settings As IsolatedStorageSettings = IsolatedStorageSettings.ApplicationSettings

             

               For Each a In Accomplishments

                   If settings.Contains(a.Name) Then

                       settings(a.Name) = a

                   Else

                       settings.Add(a.Name, a.GetCopy())

                   End If

               Next a

             

               settings.Save()

               MessageBox.Show(“Finished saving accomplishments”)

            End Sub

             

            Step 6 – Add the application bar

            Add the icon file

            1. In Solution Explorer, right-click the application name, and then add an existing item. The Add Existing Item dialog box is displayed.
            2. Browse to one of the following folders to locate the standard icons:
              • C:Program FilesMicrosoft SDKsWindows Phonev7.0Iconsdark
              • C:Program Files (x86)Microsoft SDKsWindows Phonev7.0Iconsdark
            3. Select the appbar.save.rest.png icon, and then click Add.
            4. In Solution Explorer, select the appbar.save.rest.png file.
            5. In the Properties window, change the Build Action property to “Content”.
            6. Change the Copy to Output Directory property to “Copy if newer”.
            7. Change the File Name property to “AppBarSave.png”.

            Add the application bar

            1. Open the MainPage.xaml.vb page.
            2. After the OnNavigatedFrom method, add the following code:

              Private Sub AppBarSave_Click(ByVal sender As Object, ByVal e As EventArgs)

                   vm.SaveAccomplishments()

              End Sub

            3. Open the MainPage.xaml page.
            4. Replace the <phone:PhoneApplicationPage.ApplicationBar> tag with the following XAML code:

              <phone:PhoneApplicationPage.ApplicationBar>

                  <shell:ApplicationBar IsVisible=”True” IsMenuEnabled=”True” >

                      <shell:ApplicationBarIconButton IconUri=”AppBarSave.png” Text=”Save”  Click=”AppBarSave_Click” />

                  </shell:ApplicationBar>

              </phone:PhoneApplicationPage.ApplicationBar>

            Voila! Now your model-view-viewmodel pattern for Windows Phone application is ready! You just need to build and debug the application.

            Step 7 – Build and debug the application

            1. To build the application, select Build > Build Solution. The project should build without any errors. If there are errors, check the earlier steps, correct the errors, and then build the application again.
            2. To debug the application, set the deployment target of the application to “Windows Phone 7 Emulator”.
            3. Select Debug > Start Debugging. The emulator window is displayed.
            4. To test whether the view is bound to the model, enter appropriate values in the Items Collected boxes.
            5. To test the data converter, select the Level 1 check box.
            6. To test the page state, click the Start button, and then click the Back button. The application resumes, and the page state is maintained.
            7. To test the data in isolated storage, click the Save button. The message “Finished saving accomplishments” is displayed. Click the Start button, and then select “MVVMTestApp”. A new instance of the application is launched, containing the data that you had saved in isolated storage.

            Step 8 – Rebuild in the release mode before publishing

            1. On the standard toolbar, change the configuration manager to Release.
            2. To rebuild the application, select Build > Rebuild. The XAP file of the application is generated.

            Finally, to submit your application to the market place, you can refer to upload your application walkthrough.

            Summary

            That’s it! You have now successfully implemented the model-view-viewmodel pattern for the Windows Phone application, that too in just 8 simple steps!

            You can find the full source code for the Model-View-ViewModel Pattern application here.

            Avatar

            Follow    

            No Comments.