17 min read

In this article by Abhishek Sur, author of Visual Studio 2013 and .NET 4.5 Expert Cookbook, we will build your first Windows Phone 8 application following the MVVM pattern. We will work with Launchers and Choosers in a Windows Phone, relational databases and persistent storage, and notifications in a Windows Phone

(For more resources related to this topic, see here.)

Introduction

Windows Phones are the newest smart device that has come on to the market and host the Windows operating system from Microsoft. The new operating system that was recently introduced to the market significantly differs from the previous Windows mobile operating system. Microsoft has shifted gears on producing a consumer-oriented phone rather than an enterprise mobile environment. The operating system is stylish and focused on the consumer. It was built keeping a few principles in mind:

  • Simple and light, with focus on completing primary tasks quickly
  • Distinct typography (Segoe WP) for all its UI
  • Smart and predefined animation for the UI
  • Focus on content, not chrome (the whole screen is available to the application for use)
  • Honesty in design

Unlike the previous Windows Phone operating system, Windows Phone 8 is built on the same core on which Windows PC is now running. The shared core indicates that the Windows core system includes the same Windows OS, including NT Kernel, NT filesystem, and networking stack. Above the core, there is a Mobile Core specific to mobile devices, which includes components such as Multimedia, Core CLR, and IE Trident, as shown in the following screenshot:

Visual Studio 2013 and .NET 4.5 Expert Cookbook

In the preceding screenshot, the Windows Phone architecture has been depicted. The Windows Core System is shared between the desktop and mobile devices. The Mobile Core is specific to mobile devices that run Windows Phone Shell, all the apps, and platform services such as background downloader/uploader and scheduler.

It is important to note that even though both Windows 8 and Windows Phone 8 share the same core and most of the APIs, the implementation of APIs is different from one another. The Windows 8 APIs are considered WinRT, while Windows Phone 8 APIs are considered Windows Phone Runtime (WinPRT).

Building your first Windows Phone 8 application following the MVVM pattern

Windows Phone applications are generally created using either HTML5 or Silverlight. Most of the people still use the Silverlight approach as it has a full flavor of backend languages such as C# and also the JavaScript library is still in its infancy. With Silverlight or XAML, the architecture that always comes into the developer’s mind is MVVM. Like all XAML-based development, Windows 8 Silverlight apps also inherently support MVVM models and hence, people tend to adopt it more often when developing Windows Phone apps. In this recipe, we are going to take a quick look at how you can use the MVVM pattern to implement an application.

Getting ready

Before starting to develop an application, you first need to set up your machine with the appropriate SDK, which lets you develop a Windows Phone application and also gives you an emulator to debug the application without a device. The SDK for Windows Phone 8 apps can be downloaded from Windows Phone Dev Center at http://dev.windowsphone.com. The Windows Phone SDK includes the following:

  • Microsoft Visual Studio 2012 Express for Windows Phone
  • Microsoft Blend 2012 Express for Windows Phone
  • The Windows Phone Device Emulator
  • Project templates, reference assemblies, and headers/libraries
  • A Windows 8 PC to run Visual Studio 2012 for Windows Phone

After everything has been set up for application development, you can open Visual Studio and create a Windows Phone app. When you create the project, it will first ask the target platform; choose Windows Phone 8 as the default and select OK. You need to name and create the project.

How to do it…

Now that the template is created, let’s follow these steps to demonstrate how we can start creating an application:

  1. By default, the project template that is loaded will display a split view with the Visual Studio Designer on the left-hand side and an XAML markup on the right-hand side. The MainPage.xaml file should already be loaded with a lot of initial adjustments to support Windows Phone with factors. Microsoft makes sure that they give the best layout to the developer to start with. So the important thing that you need to look at is defining the content inside the ContentPanel property, which represents the workspace area of the page.

    The Visual Studio template for Windows Phone 8 already gives you a lot of hints on how to start writing your first app. The comments indicate where to start and how the project template behaves on the code edits in XAML.

  2. Now let’s define some XAML designs for the page. We will create a small page and use MVVM to connect to the data. For simplicity, we use dummy data to show on screen. Let’s create a login screen for the application to start with.
  3. Add a new page, call it Login.xaml, and add the following code in ContentPanel defined inside the page:
    <Grid x_Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" VerticalAlignment="Center">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                
                <TextBlock Text="UserId" Grid.Row="0" Grid.Column="0"
                  HorizontalAlignment="Right" VerticalAlignment="Center"/>
                <TextBox Text="{Binding UserId, Mode=TwoWay}"
                   Grid.Row="0"Grid.Column="1" InputScope="Text"/>
                <TextBlock Text="Password" Grid.Row="1" Grid.Column="0"
                   HorizontalAlignment="Right" VerticalAlignment="Center"/>
                <PasswordBox x_Name="txtPassword" Grid.Row="1" Grid.Column="1"
                   PasswordChanged="txtPassword_PasswordChanged"/>
                <Button Command="{Binding LoginCommand}" Content="Login"Grid.Row="2"
                   Grid.Column="0" />
                <Button Command="{Binding ClearCommand}" Content="Clear"Grid.Row="2"
                   Grid.Column="1" />
            </Grid>

    In the preceding UI Design, we added a TextBox and a PasswordBox inside ContentPanel. Each TextBox has an InputScope property, which you can define to specify the behavior of the input. We define it as Text, which specifies that the TextBox can have any textual data. The PasswordBox takes any input from the user, but shows asterisks (*) instead of the actual data. The actual data is stored in an encrypted format inside the control and can only be recovered using its Password property.

  4. We are going to follow the MVVM pattern to design the application. We create a folder named Model in the solution and put a LoginDataContext class in it. This class is used to generate and validate the login of the UI.
  5. Inherit the class from INotifyPropertyChanged, which indicates that the properties can act by binding with the corresponding DependencyProperty that exists in the control, thereby interacting to and fro with the UI.
  6. We create properties for UserName, Password, and Status, as shown in the following code:
            private string userid;
            public string UserId
            {
                get { return userid; }
                set 
                { 
                    UserId = value;
                    this.OnPropertyChanged("UserId");
                }
            }
    
            private string password;
            public string Password
            {
                get { return password; }
                set { password = value; this.OnPropertyChanged("Password"); }
            }
     public bool Status { get; set; }

    You can see in the preceding code that the property setter invokes an OnPropertyChanged event. This ensures that the update on the properties is reflected in the UI control:

    public ICommand LoginCommand
            {
                get
                {
                    return new RelayCommand((e) =>
                    {
                        this.Status = this.UserId == "Abhishek" && this.Password == "winphone";
    
                        if (this.Status)
                        {
                            var rootframe = App.Current.RootVisual as PhoneApplicationFrame;
                            rootframe.Navigate(new Uri(string.Format
    ("/FirstPhoneApp;component/MainPage.xaml?name={0}",this.UserId),
                            UriKind.Relative));
                        }
                    });
                }
            }
            public ICommand ClearCommand
            {
                get
                {
                    return new RelayCommand((e) =>
                    {
                        this.UserId = this.Password = string.Empty;
                    });
                }
            }
  7. We also define two more properties of type ICommand. The UI button control implements the command pattern and uses an ICommand interface to invoke a command. The RelayCommand used on the code is an implementation of the ICommand interface, which could be used to invoke some action.
  8. Now let’s bind the Text property of the TextBox in XAML with the UserId property, and make it a TwoWay binding. The binder automatically subscribes to the PropertyChanged event. When the UserId property is set and the PropertyChanged event is invoked, the UI automatically receives the invoke request of code, which updates the text in the UI.
  9. Similarly, we add two buttons and name them Login and Clear and bind them with the properties LoginCommand and ClearCommand, as shown in the following code:
    <Button Command="{Binding LoginCommand}" Content="Login" Grid.Row="2" Grid.Column="0" />
    <Button Command="{Binding ClearCommand}" Content="Clear" Grid.Row="2" Grid.Column="1" />

    In the preceding XAML, we defined the two buttons and specified a command for each of them.

  10. We create another page so that when the login is successful, we can navigate the Login page to somewhere else. Let’s make use of the existing MainPage.xaml file as follows:
    <StackPanel x_Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock Text="MY APPLICATION" x_Name="txtApplicationDescription"Style="
    {StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
                <TextBlock Text="Enter Details" Margin="9,-7,0,0"Style="
    {StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
  11. We add the preceding XAML to show the message that is passed from the Login screen.
  12. We create another class and name it MainDataContext. We define a property that will hold the data to be displayed on the screen.
  13. We go to Login.xaml.cs created as a code-behind of Login.xaml, create an instance of LoginDataContext, and assign it to DataContext of the page. We assign this inside the InitializeComponent method of the class, as shown in the following code:
    this.DataContext = new LoginDataContext();
  14. Now, go to Properties in the Solution Explorer pane, open the WMAppManifest file, and specify Login.xaml as the Navigation page. Once this is done, if you run the application now in any of the emulators available with Visual Studio, you will see what is shown in the following screenshot:

    Visual Studio 2013 and .NET 4.5 Expert Cookbook

    You can enter data in the UserId and Password fields and click on Login, but nothing happens.

  15. Put a breakpoint on LoginCommand and press Login again with the credentials, and you will see that the Password property is never set to anything and evaluates to null. Note that, PasswordBox in XAML does not support binding to its properties. To deal with this, we define a PasswordChanged event on PasswordBox and specify the following code:
    private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
            {
                this.logindataContext.Password = txtPassword.Password;
            }

    The preceding code will ensure that the password goes properly to the ViewModel.

  16. Finally, clicking on Login, you will see Status is set to true.
  17. However, our idea is to move the page from the Login screen to MainPage.xaml. To do this, we change the LoginCommand property to navigate the page, as shown in the following code:
    if (this.Status)
    {
         var rootframe = App.Current.RootVisual as PhoneApplicationFrame;
         rootframe.Navigate(new Uri(string.Format("/FirstPhoneApp;component/MainPage.xaml?name={0}", this.UserId), UriKind.Relative));
    }

    Each WPF app contains an ApplicationFrame class that is used to show the UI. The application frame can use the navigate method to navigate from one page to another. The navigate method uses NavigationService to redirect the page to the URL provided. Here in the code, after authentication, we pass UserId as querystring to MainPage.

  18. We design the MainPage.xaml file to include a pivot control. A pivot control is just like traditional tab controls, but looks awesome in a phone environment. Let’s add the following code:
    <phone:Pivot>
                    <phone:PivotItem Header="Main">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Choose your avatar" />
                            <Image x_Name="imgSelection" Source="{Binding AvatarImage}"/>
                            <Button x_Name="btnChoosePhoto" ClickMode="Release"Content="Choose Photo" 
    Command="{Binding ChoosePhoto}" />
                        </StackPanel>
                    </phone:PivotItem>
                    <phone:PivotItem Header="Task">
                        <StackPanel>
                            <phone:LongListSelector ItemsSource="{Binding LongList}" />
                        </StackPanel>
                    </phone:PivotItem>
                </phone:Pivot>
  19. The phone tag is referred to a namespace that has been added automatically in the header where the Pivot class exists. In the previously defined Pivot class, there are two PivotItem with headers Main and Task. When Main is selected, it allows you to choose a photo from MediaLibrary and the image is displayed on Image Control. The ChoosePhoto command defined inside MainDataContext sets the image to its source, as shown in the following code:
    public ICommand ChoosePhoto
    {
        get
        {
            return new RelayCommand((e) =>
            {
                PhotoChooserTask pTask = new PhotoChooserTask();
                pTask.Completed += pTask_Completed;
                pTask.Show();
    
            });
        }
    }
    void pTask_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK)
        {
            var bitmap = new BitmapImage();
            bitmap.SetSource(e.ChosenPhoto);
            this.AvatarImage = bitmap;
        }
    }

    In the preceding code, the RelayCommand that is invoked when the button is clicked uses PhotoChooserTask to select an image from MediaLibrary and that image is shown on the AvatarImage property bound to the image source.

  20. On the other hand, the other PivotItem shows LongList where the ItemsSource is bound to a long list of strings, as shown in the following code:
    public List<string> LongList
            {
                get
                {
                    this.longList = this.longList ?? this.LoadList();
                    return this.longList;
                }
            }

    The long list can be anything, a long list that is needed to be shown in the ListBox class.

How it works…

Windows Phone, being an XAML-based technology, uses Silverlight to generate UI and controls supporting the Model-View-ViewModel (MVVM) pattern. Each of the controls present in the Windows Phone environment implements a number of DependencyProperties. The DependencyProperty is a special type of property that supports DataBinding. When bound to another CLR object, these properties try to find the INotifyPropertyChanged interface and subscribe to the PropertyChanged event. When the data is modified in the controls, the actual bound object gets modified automatically by the dependency property system, and vice versa.

Similar to normal DependencyProperties, there is a Command property that allows you to call a method. Just like the normal property, Command implements the ICommand interface and has a return type Action that maps to Command. The RelayCommand here is an implementation of ICommand interfaces, which can be bound to the Command property of Button.

There’s more…

Now let’s talk about some other options, or possibly some pieces of general information that are relevant to this task.

Using ApplicationBar on the app

Just like any of the modern smartphones, Windows Phones also provides a standard way of communicating with any application. Each application can have a standard set of icons at the bottom of the application, which enable the user to perform some actions on the application. The ApplicationBar class is present at the bottom of any application across the operating system and hence, people tend to expect commands to be placed on ApplicationBar rather than on the application itself, as shown in the following screenshot. The ApplicationBar class accepts 72 pixels of height, which cannot be modified by code.

Visual Studio 2013 and .NET 4.5 Expert Cookbook

When an application is open, the application bar is shown at the bottom of the screen. The preceding screenshot shows how the ApplicationBar class is laid out with two buttons, login and clear. Each ApplicationBar class can also associate a number of menu items for additional commands. The menu could be opened by clicking on the button in the left-hand side of ApplicationBar.

The page of Windows Phone allows you to define one application bar. There is a property called ApplicationBar on PhoneApplicationPage that lets you define the ApplicationBar class of that particular page, as shown in the following screenshot:

   <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar>
            <shell:ApplicationBarIconButton Click="ApplicationBarIconButton_Click" Text="Login"
IconUri="/Assets/next.png"/>
            <shell:ApplicationBarIconButton Click="ApplicationBarIconButtonSave_Click" Text="clear"
IconUri="/Assets/delete.png"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Click="about_Click" Text="about" />
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>

In the preceding code, we defined two ApplicationBarIconButton classes. Each of them defines the Command items placed on the ApplicationBar class. The ApplicationBar.MenuItems method allows us to add menu items to the application. There can be a maximum of four application bar buttons and four menus per page. The ApplicationBar button also follows a special type of icon. There are a number of these icons added with the SDK, which could be used for the application. They can be found at DriveNameProgram FilesMicrosoft SDKs Windows Phonev8.0Icons.

There are separate folders for both dark and light themes. It should be noted that ApplicationBar buttons do not allow command bindings.

Tombstoning

When dealing with Windows Phone applications, there are some special things to consider. When a user navigates out of the application, the application is transferred to a dormant state, where all the pages and state of the pages are still in memory but their execution is totally stopped. When the user navigates back to the application again, the state of the application is resumed and the application is again activated. Sometimes, it might also be possible that the app gets tombstoned after the user navigates away from the app. In this case, the app is not preserved in memory, but some information of the app is stored. Once the user comes back to the app, the application needs to be restored, and the application needs to resume in such a way that the user gets the same state as he or she left it. In the following figure, you can see the entire process:

Tombstoning

There are four states defined, the first one is the Not Running state where there is no existence of the process in memory. The Activated state is when the app is tapped by the user. When the user moves out of the app, it goes from Suspending to Suspended. It can be reactivated or it will be terminated after a certain time automatically.

Let’s look at the Login screen, where you might sometimes tombstone the login page while entering the user ID and password. To deal with storing the user state data before tombstoning, we use PhoneApplicationPage. The idea is to serialize the whole DataModel once the user navigates away from the page and retrieves the page state again when it navigates back.

Let’s annotate the UserId and Password of the LoginDataContext with DataMember and LoginDataContext with DataContract, as shown in the following code:

[DataContract]
    public class LoginDataContext : PropertyBase
    {
        private string userid;
        [DataMember]
        public string UserId
        {
            get { return userid; }
            set 
            { 
                UserId = value;
                this.OnPropertyChanged("UserId");
            }
        }

        private string password;
        [DataMember]
        public string Password
        {
            get { return password; }
            set { password = value; this.OnPropertyChanged("Password"); }
        }
}

The DataMember property will indicate that the properties are capable of serializing. As the user types into these properties, the properties get filled with data so that when the user navigates away, the model will always have the latest data present.

In LoginPage, we define a property called _isNewPageInstance and set it to false, and in constructor, we set it to true. This will indicate that only when the page is instantiated, _isNewPageInstance is set to true.

Now, when the user navigates away from the page, OnNavigatedFrom gets called. If the user navigates from the page, we save ViewModel into State as shown in the following code:

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
    {
        // Save the ViewModel variable in the page''s State dictionary.
        State[""ViewModel""] = logindataContext;
    }
}

Once DataModel is saved in the State object, it is persistent and can be retrieved later on when the application is resumed as follows:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (_isNewPageInstance)
    {
        if (this.logindataContext == null)
        {
            if (State.Count > 0)
            {
                this.logindataContext = (LoginDataContext)State[""ViewModel""];
            }
            else
            {
                this.logindataContext = new LoginDataContext();
            }
        }
        DataContext = this.logindataContext;
    }
    _isNewPageInstance = false;
}

When the application is resumed from tombstoning, it calls OnNavigatedTo and retrieves DataModel back from the state.

Summary

In this article, we learned device application development with the Windows Phone environment. It provided us with simple solutions to some of the common problems when developing a Windows Phone application.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here