CHAPTER 2

image

Implementing the View

The main objective of following the MVVM design pattern is to provide separation between what an application looks like (the user interface look and feel), and how the application acts on user actions (implementing the business logic and integrating with the data source). After creating a blank XAML Windows 8 application in Chapter 1, we need to define the presentation layer of the FinanceHub application. The View represents the definition of the applications’ user interface in MVVM design pattern. This chapter will focus on how the application looks, so we will be mainly focusing on the following points with minimal focus on the code-behind:

  • Defining application deployment package and runtime configuration properties
  • Defining the resources to drive styles and themes of the application
  • Developing application user interface (the view) using XAML

You will be updating the blank project further to define the view of the FinanceHub application.

Customizing Deployment Package and Runtime Configuration Properties

It’s odd to set up the deployment package and runtime configuration properties in the beginning but it’s a good practice to decide your application deployment properties up front to match your application’s features and functionalities as well as the application color scheme theme. This is getting more important since you are deploying applications to app stores (in our case, Windows Application Store) and you want to make sure that your application deployment design is considered from the beginning. With this approach you can create a compelling end-to-end branding story making your application more visible and attractive. The other point you need to consider from the beginning is the minimum requirements and qualifications your application needs to meet in order to publish your application to specific app stores. These can vary by app store (e.g., Windows app store vs. Apple’s and Google’s). At present for Windows app store the minimum requirement is to provide custom application–specific app logos and color scheme; otherwise you will see the default ones. Let’s start!

In Windows 8 application, the Package.appxmanifest file manages deployment application package and runtime configuration properties. For the FinanceHub application project we will change the background color of the tile and different application logos. Open the blank project you created as part of Chapter 1 to get started.

Background Color of the Tile

I am going to select a light tile background color instead of the default dark tile background color for this project. In order to keep the overall color scheme in sync, we need to change the background color for the splash screen. To customize the splash screen background color; open Package.appxmanifest file and you will see four tabs. The first default tab is Application UI tab; in which you should notice Hex color value #464646 for Background Color under the Tile section. This Hex code represents dark gray color. Change it to the value #9ea7b1, which represents a light gray shade.

Application Logo Files and Splash Screen

The next step is to provide its own branding to the FinanceHub application by defining different application logos and the splash screen. For that you will be replacing default logo image files with the custom ones.

If you visit the Assets folder displayed in the Solution Explorer window; you will notice that there four logo image files were added as part of the default project:

  • Logo.png – is 150x150 pixel PNG type image file represents the main Tile logo and is referenced as Tile logo under the Application UI tab of the Package.appxmanifest file
  • SmallLogo.png – is 30x30 pixel PNG type image file represents the small tile logo and is referenced as Tile Small logo under the Application UI tab of the Package.appxmanifest file
  • SplashScreen.png – is 620x300 pixel PNG type image file represents a splash screen of the application and is referenced as Splash Screen under the Application UI tab of the Package.appxmanifest file
  • StoreLogo.png – is 50x50 pixel PNG type image file represents the deployed application logo, which displayed in Windows Store, and is referenced as Logo under the Packaging tab of the Package.appxmanifest file

I have chosen the piggy bank concept to brand the FinanceHub project and thus need to create appropriate PNG file type images with the required sizes that will replace the above-mentioned image files under the Assets folder. You can delete the existing logo and splash screen files and add your custom ones (with the same file name, file type, and file size) using Add image Existing Item option within the solution explorer window. Now you are ready to provide your own brand to the application.

image Note   You must keep custom logo and custom splash screen images as PNG file types with the above-mentioned names and image file sizes. Changes in that area will be reported as an error.

Visit Package.appxmanifest file’s Application UI and Packaging tab. If you have added the right logo files and splash screen you should not see any red X signs; otherwise you will see a red X sign explaining the problem. For demonstration purposes, I have replaced StoreLogo.png file with 80x80 file size rather than the 50x50 required file size. Now if you visit the Packaging tab, you will notice an error, as shown in Figure 2-1.

9781430249085_Fig02-01.jpg

Figure 2-1.  Demonstrating Error when the added StoreLogo.png file does not contain the required 50x50 size

At this point if you run the application; you should see a custom splash screen with our newly defined custom light background and the application without any tiles (just a blank screen) with the default dark color theme.

Enabling Customization of Application Styles and Themes

Consistent styling and theming across your application helps in providing a consistent user experience to your application users. Externalizing definition of application styles and themes as resources simplify the management and maintenance of application styling and theming.

You might have noticed that under Common folder there is a single helper file StandardStyle.xaml, which contains the set of styles that are common for Windows 8 application layout. If you open that file you will notice that Microsoft recommends not to alter this particular file and instead create a separate similar resource dictionary file that contains variations to these default styles by overriding them. You can also introduce new sets of styles based on the requirements of your application.

Adding New Resource Dictionary File

To add a new resource dictionary file, which will be used to override the default application styles and add new additional styles:

  1. Select the Common folder in the Solution Explorer windows and right click to add new item.
  2. Select Resource Dictionary item and name the file to Resources.xaml as shown in Figure 2-2.

9781430249085_Fig02-02.jpg

Figure 2-2.  Adding New Resouces.xaml Resource Dictionary File

The newly added Resources.xaml resource dictionary file is a blank file with default namespace declaration as shown below.

<ResourceDictionary
    xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
    xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml "
    xmlns:local="using:FinanceHub.Common">

</ResourceDictionary>

image Enhancements in XAML You will notice the using key word in defining the namespace in the above code snippet. With Windows 8, the XAML platform is enhanced and is available to the native environment making XAML platform a language agnostic platform (e.g., available to C++ also). As a result, XAML namespace declaration approach is changed to be more language agnostic and instead of using clr-namespace now you will be using the using keyword to decorate the namespace within XAML.

Enabling Additional Resources.xaml Resource Dictionary at Application Level

The next step is to create the Resources.xaml resource dictionary visible at the application level. For that you add ResourceDictionary, with the Source value set to the newly added Resources.xaml file, to the generic collection referenced by MergedDictionaries within the App.xaml file, as shown below.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!--
                Styles that define common aspects of the platform
                      look and feel

                Required by Visual Studio project and item
                     templates

             -->
            <ResourceDictionary
                 Source="Common/StandardStyles.xaml"/>

            <ResourceDictionary Source="Common/Resources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

image Note   Please note the order of the added ResourceDictionary element for Resources.xaml file. It is added immediately after the StandardStyles.xaml file as a last ResourceDictionary to the MergedDictionaries collection. During execution the last added ResourceDictionary to the MergedDictionaries collection will be searched first and thus if you are overriding style values with the same key name; that resource file should be added last to the collection (we’ll get to key names in the next section).

Customizing Application Theme

Windows 8 SDK provides three pre-defined Windows 8 application themes – light, dark, and high contrast – that are defined in the themeresources.xaml file that will be applicable to Windows 8 applications developed using XAML.

The default Windows 8 application theme is a dark color theme and for that you do not need to set anything. However, you can select dark and light color themes by assigning Application.RequestedTheme property to Dark or Light value within App.xaml file, as shown below:

Programmatically Setting Light Color Theme

<Application
    x:Class="FinanceHub.App"
    xmlns=
       "
http://schemas.microsoft.com/winfx/2006/xaml/presentation "
    xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml "
    xmlns:local="using:FinanceHub"
    RequestedTheme="Light" >

Programmatically Setting Dark Color Theme

<Application
    x:Class="FinanceHub.App"
    xmlns=
       "
http://schemas.microsoft.com/winfx/2006/xaml/presentation "
    xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml "
    xmlns:local="using:FinanceHub"
    RequestedTheme="Dark" >

The High Contrast theme is automatically activated by Windows once the corresponding option is selected in the Control Panel.

image Note   You can locate themeresources.xaml file at C:Program Files (x86)Windows Kits8.0Includewinrtxamldesign for 64-bit OS and C:Program FilesWindows Kits8.0Includewinrtxamldesign for 32-bit OS. I highly recommend you quickly go through these styles to get idea of different types of controls and related style definitions in the Windows 8 application.

We will change the default dark color theme to a custom light color theme. For FinanceHub application we would need to override theme resources related to AppBar, ApplicationPage Background and ProgressBar, ComboBox, and ListView controls by adding light color values with the Key name values in the newly added Resources.xaml file, which are same as the key name values defined in the themeresources.xaml file. The following code snippet demonstrates this configuration:

<!--Color resources-->
<Color x:Key="AppPurpleColor">#FF585A8E</Color>
<Color x:Key="AppLightPurpleColor">#6a7bba</Color>

<!--Theme overrides-->
<SolidColorBrush
    x:Key="AppBarBackgroundThemeBrush"
    Color="#9ea7b1" />
<SolidColorBrush
    x:Key="AppBarBorderThemeBrush"
    Color="#93a8c8" />
<SolidColorBrush
    x:Key="ApplicationPageBackgroundThemeBrush"
    Color="#B3BDE1"/>
<SolidColorBrush
    x:Key="ProgressBarIndeterminateForegroundThemeBrush"
    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush
    x:Key="ComboBoxItemSelectedBackgroundThemeBrush"
    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush
    x:Key="ComboBoxItemSelectedForegroundThemeBrush"
    Color="White" />
<SolidColorBrush
    x:Key="ComboBoxItemSelectedPointerOverBackgroundThemeBrush"
    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush
    x:Key="ComboBoxSelectedBackgroundThemeBrush"
    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush    x:Key="ComboBoxSelectedPointerOverBackgroundThemeBrush"    
Color="{StaticResource AppPurpleColor}" />

<SolidColorBrush
    x:Key="ListViewItemPlaceholderBackgroundThemeBrush"
    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush
    x:Key="ListViewItemSelectedBackgroundThemeBrush"

    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush
    x:Key="ListViewItemSelectedPointerOverBackgroundThemeBrush"
    Color="{StaticResource AppPurpleColor}" />
<SolidColorBrush
    x:Key="ListViewItemSelectedPointerOverBorderThemeBrush"
    Color="{StaticResource AppPurpleColor}" />

Next you need to open the StandardStyles.xaml resource file, which is available under the Common folder and merge Resources.xaml dictionary with the default theme dictionary by adding the following markup.

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Default">
        <x:String x:Key="BackButtonGlyph"></x:String>
        <x:String             x:Key="BackButtonSnappedGlyph"></x:String>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Resources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    ....

Now if you run the project you will notice that the application page background has changed to the light gray color, which was set as custom theme color, instead of the dark gray color.

This exercise is also a great start to make a place holder for future customization of styles related to the application. We will update the Resources.xaml file as we continue developing the view of the application throughout the remaining chapter.

Developing User Interface

Let’s build a user interface for the FinanceHub application by adding the required XAML pages as views under the View folder.

The Main Startup Page – MainPage.xaml

We will be treating MainPage.xaml as the main page container that you can compare as a master page for any ASP.NET application or shell of the Prism framework. For that under the View folder Add Blank Page item with the name set to MainPage.xaml as shown in Figure 2-3.

9781430249085_Fig02-03.jpg

Figure 2-3.  Adding New XAML Blank Page as MainPage.xaml under View folder

This page definition, as shown below, is very much similar to the original MainPage.xaml file, which still exists in the root folder.

<Page
    x:Class="FinanceHub.View.MainPage"
    IsTabStop="false"
    xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
    xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml "
    xmlns:local="using:FinanceHub.View"
    xmlns:d=" http://schemas.microsoft.com/expression/blend/2008 "
    xmlns:mc=
     "
http://schemas.openxmlformats.org/markup-compatibility/2006 "
    mc:Ignorable="d" Margin="-1,0,1,0">

    <Grid Background="{StaticResource
          ApplicationPageBackgroundThemeBrush}">


    </Grid>
</Page>

You do not need to keep two MainPage files, so delete the one available at the root project level. Since we moved the location of the starting MainPage under the View folder, in order to run the project successfully you need to visit the app.xaml.cs file and change starting page from MainPage to FinanceHub.View.MainPage as shown below.

var rootFrame = new Frame();
if (!rootFrame.Navigate(typeof(FinanceHub.View.MainPage )))
{
    throw new Exception("Failed to create initial page");
}

Now if you run the project it should locate the blank MainPage as a starting page and will run successfully.

Adding Bottom Application Bar – MainPage.xaml

Microsoft introduced the Application Bar (AKA app bar) UI element to the Windows 8 application that typically appears at the top and/or bottom of the screen. Typically the top app bar represents navigation and the bottom app bar represents commands and tools related to the application. App Bar is not mandatory to the application and if you want you can define either top or bottom or both app bars. By default it is not visible and you can invoke it (make it visible) by right-clicking, pressing Windows + Z or by swiping from the bottom or top of the screen.

The AppBar user control can contain one or more application UI controls to create the navigation, commands, and tool bar. In XAML you can add AppBar control as a top app bar by assigning it to the TopAppBar property of Page and add bottom app bar by assigning AppBar control to the BottomAppBar property of Page control.

For FinanceHub application, we will have the bottom app bar, which will be available to all pages of the application, containing commands to add and remove stock watch list. Add the following to MainPage.xaml file.

<!--Bottom Application bar-->
<Page.BottomAppBar>
    <AppBar x:Name="BottomAppBar1" Padding="10,0,10,0">

    </AppBar>
</Page.BottomAppBar>
 

Next add two buttons – Add and Remove – in the bottom app bar as shown below.

<Page.BottomAppBar>
    <AppBar x:Name="BottomAppBar1" Padding="10,0,10,0">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50*"/>
                <ColumnDefinition Width="50*"/>
            </Grid.ColumnDefinitions>

            <StackPanel                 x:Name="RightPanel" Orientation="Horizontal"
                Grid.Column="1" HorizontalAlignment="Right">
                <Button x:Name="Remove" BorderBrush="{x:Null}"                    
                     Click="RemoveStock">

                    <Button.ContentTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Image
                                     Source="../Assets/minus.png"                                    
                     Height="48" Width="48"/>

                                <TextBlock Text="Remove"
                                    HorizontalAlignment="Center" >
                                </TextBlock>

                            </StackPanel>
                        </DataTemplate>
                    </Button.ContentTemplate>
                </Button>
                <Button x:Name="Add" Content="Add"                    
                     BorderBrush="{x:Null}"

                    Click="AddNewStock">
                    <Button.ContentTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Image Source="../Assets/add.png"                                    
                    Height="48" Width="48"/>

                                <TextBlock Text="Add"                                    
                     HorizontalAlignment="Center" >
                                </TextBlock>

                            </StackPanel>
                        </DataTemplate>
                    </Button.ContentTemplate>
                </Button>
            </StackPanel>
        </Grid>
    </AppBar>
</Page.BottomAppBar>
 

Two main things to note. First you will see a reference to two image files – minus.png and add.png – under the Assets folder. Please add these two files (provided as part of the source code with your purchase of this book) to display them as Remove and Add buttons respectively.

Second you will notice that each button – Add and Remove – has a Click event associated with it. To create a Click event handler for Add and Remove buttons named AddNewStock and RemoveStock respectively, right-click on the event handler name and select navigate to event handler so Visual Studio will add the code-behind for the events, which you can confirm by visiting the MainPage.xaml.cs file.

If you run the project at this point and swipe at the bottom or top of the screen edge you should see a bottom app bar displaying right aligned Add and Remove buttons as shown in Figure 2-4. However, if you click or tap on those buttons nothing will happen since we have not implemented the business logic yet.

9781430249085_Fig02-04.jpg

Figure 2-4.  FinanceHub Application with Bottom Application Bar

image Note   Visual Studio 2012 has a Windows 8 application simulator where you can experiment with common touch and rotate events. To run and debug application in the Simulator mode you should select Simulator from the drop-down list next to the Start Debugging button on the debugger Standard toolbar in Visual Studio 2012. You can get more details on this by visiting MSDN site – http://msdn.microsoft.com/en-us/library/hh441475.aspx.

As discussed earlier MainPage.xaml is a master navigation page that contains the bottom app bar and this page needs to be visible all the time throughout the application. You can achieve this by defining a Frame named mainPageFrame within the MainPage.xaml file as shown below. We will set this frame as the main frame for navigation, keeping Mainpage in view all the time and providing navigation to different application pages using this frame.

<Grid
    Background="{StaticResource     ApplicationPageBackgroundThemeBrush}"
    Style="{StaticResource LayoutRootStyle}">
    <Frame x:Name="mainPageFrame"/>
</Grid>

Also we will be developing a NavigationService at a later stage to separate the presentation and business logic following MVVM design pattern. In order to implement that in the future let’s expose this mainPageFrame frame as a property by adding the following code in the MainPage.xaml.cs code-behind.

/// Application wide Frame control to be used ///in Navigation Service
public Frame AppFrame
{
    get
    {
        return this.mainPageFrame;
    }
}

Setting Up Remaining Custom Resources and Styles in Resources.xaml

Before we further add other stock-related XAML pages let’s add additional styles required to support development. For that, open Resources.xaml file and add the following custom resources to be used to display stock-related details.

<!--Custom resources-->
<SolidColorBrush x:Key="ApplicationTitleColorBrush"
    Color="{StaticResource AppLightPurpleColor}" />
<SolidColorBrush x:Key="StockTilesBackgroundBrush"     Color="#f8f5f5"/>
<SolidColorBrush x:Key="StockDetailForegroundBrush"     Color="DarkBlue" />
<SolidColorBrush x:Key="StockDetailLightBlueForegroundBrush"     Color="#759CC8" />
<SolidColorBrush x:Key="StockChangePositiveForegroundBrush"     Color="DarkGreen" />
<SolidColorBrush x:Key="StockChangeNegativeForegroundBrush"     Color="DarkRed" />
<SolidColorBrush x:Key="StockCaptionBrush" Color="DarkGray" />

Next add the following styles: DetailTextStyle, CaptionTextStyle, and HeaderTextStyle that would drive the text styles in stock-related pages. Please notice that we will use two resources, as defined above, to determine the foreground color of the DetailTextStyle and HeaderTextStyle styles.

<!--Custom Styles -->
<Style x:Key="DetailTextStyle" TargetType="TextBlock" >
    <Setter Property="FontWeight" Value="SemiBold"/>
    <Setter Property="Foreground"         Value="{StaticResource StockDetailForegroundBrush}"/>
    <Setter Property="FontSize" Value="22"/>
    <Setter Property="Margin" Value="5" />
</Style>

<Style x:Key="CaptionTextStyle" TargetType="TextBlock" >
    <Setter Property="FontWeight" Value="SemiBold"/>
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="FontSize" Value="22"/>
    <Setter Property="Margin" Value="5" />
</Style>

<Style x:Key="HeaderTextStyle" TargetType="TextBlock"
    BasedOn="{StaticResource CaptionTextStyle}" >
    <Setter Property="Foreground"         Value="{StaticResource ApplicationTitleColorBrush}"/>
    <Setter Property="FontSize" Value="26"/>
</Style>

Adding Stocks Page – StocksPage.xaml

We are going to follow a Hierarchical navigation pattern to build the FinanceHub application. The Hierarchical navigation pattern follows the Hub – Spoke – Details model, as shown in Figure 2-5. The Hierarchical pattern presents the Items (Hub), Sub items or first-level details (Spoke), and further content details (Details).

9781430249085_Fig02-05.jpg

Figure 2-5.  Hierarchical Navigation Pattern for Windows 8 Applications

For simplicity and to maintain our focus on implementation of MVVM and not developing full commercial application, this book will implement Hub (List of Stocks) and Spoke (Details of Stock) only. This section covers the user interface implementation of the Hub – the Stock page, which will list a set of stocks added to your watch list and each stock will be represented as an individual tile.

Windows 8 comes up with a set of XAML page templates to build Windows 8 applications easily and follow design principles of Windows 8 application user interface consistently across application. One of the available templates is an Item Page template, which displays a collection of items. This template is suitable to display stocks to our application. Add a stock page named StocksPage.xaml of type Item Page under the View folder.

When you add an Item type page for the first time in your project you should be receiving a pop-up message as shown in Figure 2-6 asking permission to add required dependency files under Common folder automatically. Please make sure you click the Yes button to add these required files automatically; otherwise you have to add/code them manually.

9781430249085_Fig02-06.jpg

Figure 2-6.  Getting Permission to Add Required Dependencies Files while Adding an Item Page

You will notice that 6 utility classes and ReadMe.txt files are added (shown in Figure 2-7) as dependency classes under Common folder.

9781430249085_Fig02-07.jpg

Figure 2-7.  Automatically Added 6 Utility Classed Under Common Folder

Set Application Name

We need to display the application name across the application and thus we need to move the string resource named AppName from its default location StocksPage.xaml file to the App.xaml file, making it an application-level resource rather than just a page-specific resource.

To implement this first, open StocksPage.xaml file and delete the following line of code that declares the key AppName under Page.Resources, since we will declare it in the App.xaml file.

<!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
<x:String x:Key="AppName">My Application</x:String>
 

Now open App.xaml file and declare key AppName under ResourceDictionary that will be used to display the application name – Finance Hub – in the application.

<ResourceDictionary>
    . . .

    <x:String x:Key="AppName">Finance Hub</x:String>
</ResourceDictionary>
 

You will notice in the design view of the StocksPage.xaml that the application name has changed from My Application to Finance Hub as page title in the page header section of the page.

Display Application Logo with Application Name

In order to display an application logo with the application name you need to change the existing code a little bit. Before changing the code first visit the Assets folder and add AppLogo.png image file, which will be used to display the application logo.

Now open StocksPage.xaml file and add the horizontal oriented StackPanel that will contain the application logo as shown below.

<StackPanel Orientation="Horizontal" Grid.Column="1" Margin="90,0,0,0">
    <Image
        Source="../Assets/AppLogo.png" Stretch="None"
        Height="80" Width="80" Margin="10" ></Image>
    <TextBlock x:Name="pageTitle"  Text="{StaticResource AppName}"
        Style="{StaticResource PageHeaderTextStyle}"
        Foreground="{StaticResource ApplicationTitleColorBrush}"/>
</StackPanel>
 

At this point if you look at the design view, you should be seeing the application logo and application name. At runtime the back button will not be displayed if you do not have multiple pages but it will keep the space required by the back button by default. To adjust this you need to set the Visibility property of the back button to Collapsed. Revisit StocksPage.xaml and make the appropriate modifications as shown below.

<Button x:Name="backButton" Visibility="Collapsed" Click="GoBack"
    IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}"
    Style="{StaticResource BackButtonStyle}"/>

Now you will notice that the back button is not displayed and the space is adjusted properly.

Finally add StocksPage.xaml page as a navigation page to be displayed in the mainPageFrame to enable showing list of stocks as a startup page. For this revisit MainPage.xaml.cs file and add the following in the existing OnNavigateTo event.

/// Invoked when this page is about to be displayed in a Frame.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    this.mainPageFrame.Navigate(typeof(StocksPage));
}

Display One Stock for Demonstration Purpose

Open StocksPage.xaml.cs file and first you need to add Stock class as shown below that would maintain the hard-coded stock information – stock symbol, open price, change in price, and current price.

#region Stock class
public class Stock
{
    public string Symbol { get; set; }
    public decimal OpenPrice { get; set; }
    public decimal Change { get; set; }
    public decimal CurrentPrice { get; set; }
}
#endregion
 

As you probably know, in XAML the DataTemplate class enables structuring custom and rich visual representation of the data by defining rendering of data object as a template. Before we start adding the remaining code to display the stocks first you need to create a DataTemplate with the name StockTilesTemplate in the Resources.xaml file that will control the visual representation of the stock information to be displayed on stock tiles. You would bind the above created Stock class attributes and display them appropriately within a stock tile.

<DataTemplate x:Key="StockTilesTemplate">
    <Border BorderBrush="{StaticResource AppBarBorderThemeBrush}"        
         BorderThickness="2">

        <Grid Background="{StaticResource            
         StockTilesBackgroundBrush}"

            Height="155" Width="220">
            <TextBlock                 Foreground=                    
        "{StaticResource StockDetailForegroundBrush}"

                HorizontalAlignment="Left"                 
         TextWrapping="Wrap" Text="{Binding Symbol}"

                VerticalAlignment="Top"                 
         Margin="10,10,0,0" Height="32" Width="200"

                    FontSize="24" />
            <TextBlock HorizontalAlignment="Left"                
         TextWrapping="Wrap"

                Text="{Binding CurrentPrice}"
                VerticalAlignment="Top" Margin="60,96,0,0"                
        Height="51" Width="151" FontSize="42"

                Foreground="{StaticResource                    
        StockDetailLightBlueForegroundBrush}" />

            <Path Data="M211,23" Fill="#FFBF2B00"                
        HorizontalAlignment="Left" Height="0"

                Margin="211,23,0,0" Stretch="Fill"                
        UseLayoutRounding="False"

                VerticalAlignment="Top"
                Width="0"/>
            <Path Data="M141,31 L179,31 L160,56" Fill="#FFBF2B00"                
        HorizontalAlignment="Left"

                Height="18.092" Margin="10,113.908,0,0"                
        Stretch="Fill" UseLayoutRounding="False"

                VerticalAlignment="Top" Width="27.5"                
        Visibility="Collapsed"/>

            <Path Data="M141,31 L179,31 L160,56" Fill="#FF108104"                
        HorizontalAlignment="Left"

                Height="18.092" Margin="10,120.908,0,0"                
        Stretch="Fill" UseLayoutRounding="False"

                VerticalAlignment="Top" Width="27.5"                
        RenderTransformOrigin="0.5,0.5">

                <Path.RenderTransform>
                    <CompositeTransform Rotation="180"/>
                </Path.RenderTransform>
            </Path>
            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap" Text="Open"

                VerticalAlignment="Top" Margin="10.5,47,0,0"                
        FontSize="18.667"

                 Foreground="DarkGray"/>
            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap"

                Text="{Binding OpenPrice}"
                VerticalAlignment="Top" Margin="98.5,47,0,0"                
        FontSize="18.667"

                Foreground="#6a7bba" Width="111.5"/>
            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap" Text="Change"

                VerticalAlignment="Top" Margin="10.5,74,0,0"
                Foreground="{StaticResource StockCaptionBrush}"                
        FontSize="18.667"

                RenderTransformOrigin=                    
        "0.666999995708466,0.455000013113022"/>

            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap" Text="{Binding Change}"

                VerticalAlignment="Top" Margin="98.5,74,0,0"                
        FontSize="18.667"

                Foreground="{StaticResource                    
        StockChangePositiveForegroundBrush}"                
        Width="111.5"/>

        </Grid>
    </Border>
</DataTemplate>
 

Now revisit the itemGridView GridView control in the StocksPage.xaml file and set the SelectionMode property to None to disable the selection and ItemTemplate to the StockTilesTemplate data template we just created above to display each item. The related code snippet is shown below.

<GridView
    x:Name="itemGridView"
    AutomationProperties.AutomationId="ItemsGridView"
    AutomationProperties.Name="Items"
    SelectionMode="None"
    TabIndex="1"
    Grid.Row="1"
    Margin="0,-4,0,0"
    Padding="116,0,116,46"
    ItemsSource=        "{Binding Source={StaticResource itemsViewSource}}"
    ItemTemplate="{StaticResource StockTilesTemplate}" />
 

Make similar changes to the itemListView ListView control.

<ListView
    . . ..
    SelectionMode="None"
    . . ..
    ItemTemplate="{StaticResource StockTilesTemplate}" />
 

Next just to display one stock for demonstration purposes we will hardcode one stock – MSFT – in the StocksPage.xaml code-behind. However, we will remove it and create clear separate View layer in later chapters. We will use ObservableCollection holding the stock price. For that, first you need to add reference to the System.Collections.ObjectModel as shown below in StocksPage.xaml.cs file.

using System.Collections.ObjectModel;

Next visit the LoadState method of this page and add MSFT stock related information to the ObservableCollection and assign this collection to DefaultViewModel’s Items key as shown below.

protected override void LoadState(Object navigationParameter,     Dictionary<String, Object> pageState)
{
    var collection = new ObservableCollection<Stock>();
    collection.Add(new Stock
    { Symbol = "MSFT",      
      OpenPrice = 30.05M,
       Change = 0.25M,      
      CurrentPrice = 30.30M    
      });

    this.DefaultViewModel["Items"] = collection;
}
 

Run the application in the simulation mode and you will see the application logo and application name in the application header section and MSFT stock tile with appropriate stock information displayed as shown in Figure 2-8.

9781430249085_Fig02-08.jpg

Figure 2-8.  FinanceHub Application Running with the Main Page displaying Stock Tile

Adding Stock Details Page – StockInfoView.xaml and StockDetails.xaml

If you click on the MSFT stock tile nothing will happen. Next, navigate to the implement stock details page by clicking on the stock tile, which will display a bit more information related to the clicked stock. In this chapter we will focus on building the stock detail user interface and enabling the navigation to this page. We will worry about how to bind data from the data source in later chapters.

The stock details page contains lists of stocks and will display the selected stock information in a split view. So first let’s create a view that will display selected stock information and then will create the stock details page and plug-in the stock information view to it, building complete user interface.

Adding StockInfoView.xaml User Control

Select View folder in the Solution Explorer and add a new blank UserControl type template with the name StockInfoView.xaml. The following is the default XAML code of the added user control.

<UserControl
    x:Class="FinanceHub.View.StockInfoView"
    xmlns=
       "
http://schemas.microsoft.com/winfx/2006/xaml/presentation "
    xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml "
    xmlns:local="using:FinanceHub.View"
    xmlns:d=" http://schemas.microsoft.com/expression/blend/2008 "
    xmlns:mc=
     "
http://schemas.openxmlformats.org/markup-compatibility/2006 "
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">
    
    <Grid>

    </Grid>
</UserControl>
 

Now remove the existing Grid control and let’s add required UI elements within StackPanel as shown in the following code snippet that will display the following information with Stock Details title text and related hard-coded values (for this chapter only):

  • Current Price
  • Open Price
  • Today High and Low Range
  • 52 Weeks High and Low Range
<StackPanel>
    <TextBlock Text="Stock Details"        
        Style="{StaticResource HeaderTextStyle}" Margin="5" />

    <TextBlock        
        Text="Current Price"        
        Style="{StaticResource CaptionTextStyle}" Margin="5"/>

    <TextBlock        
        Style="{StaticResource DetailTextStyle}"        
        Text="30.30"/>

    <TextBlock        
        Text="Open Price"        
        Style="{StaticResource CaptionTextStyle}" Margin="5"/>

    <TextBlock        
        Style="{StaticResource DetailTextStyle}"        
        Text="30.05"/>

    <TextBlock        
        Text="Today High and Low Range"

        Style="{StaticResource CaptionTextStyle}" Margin="5"/>
    <TextBlock        
        Style="{StaticResource DetailTextStyle}"        
        Text="30.33 - 30.05"/>

    <TextBlock        
        Text="52 Weeks High and Low Range"

        Style="{StaticResource CaptionTextStyle}" Margin="5"/>
    <TextBlock         Style="{StaticResource DetailTextStyle}"        
        Text="32.95 - 24.26"/>

</StackPanel>
 

If you look at the design view you should see the user interface of the user control as shown in Figure 2-9.

9781430249085_Fig02-09.jpg

Figure 2-9.  Design View of the StockInfoView.xaml UserControl

Please note that in a real-world application you probably would like to put more information in the stock details page.

Adding StockDetails.xaml Split Page

Again select View folder in the solution explorer and add a new Split Page template with the name StockDetails.xaml, which will display a list of items (in our case list of stocks) and the details for a selected item (in our case StockInfoView of the selected stock).

Open StocksDetails.xaml page and locate the TextBlock control with the name set to pageTitle and set Text property to AppName value as shown below.

<TextBlock x:Name="pageTitle" Grid.Column="1"
    Text="{Binding Group.Title}" Text="{StaticResource AppName}"
    Style="{StaticResource PageHeaderTextStyle}
    Foreground="{StaticResource ApplicationTitleColorBrush}"/>

Next locate primaryColumn ColumnDefinition and change the Width from 610 to 400 as shown below.

<Grid.ColumnDefinitions>
    <ColumnDefinition x:Name="primaryColumn" Width="400"/>
    <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

Now we have to make two key changes in the XAML code first to bind the list view with the stock information and second to plug in the stock information detail view to display the selected stock details.

In order to view the list of stocks; first you need to add a DataTemplate with the name StockListTemplate in Resources.xaml file similar to the one you added earlier for StocksPage.xaml.

<DataTemplate x:Key="StockListTemplate">
    <Border BorderBrush="{StaticResource AppBarBorderThemeBrush}"        
       BorderThickness="2">

        <Grid Background="#f8f5f5"  Height="110" Width="220">
            <TextBlock Foreground="{StaticResource                                      
        StockDetailForegroundBrush}"

                HorizontalAlignment="Left" TextWrapping="Wrap"                
        Text="{Binding Symbol}"

                VerticalAlignment="Top" Margin="10,10,0,0"                
        Height="32" Width="200"

                 FontSize="24" />
            <Path Data="M211,23" Fill="#FFBF2B00"                
        HorizontalAlignment="Left" Height="0"

                Margin="211,23,0,0" Stretch="Fill"                
        UseLayoutRounding="False"

                VerticalAlignment="Top"
                Width="0"/>
            <Path Data="M141,31 L179,31 L160,56"                
        Fill="#FFBF2B00" HorizontalAlignment="Left"

                Height="18.092" Margin="10,113.908,0,0"                
        Stretch="Fill" UseLayoutRounding="False"

                VerticalAlignment="Top" Width="27.5"                
        Visibility="Collapsed"/>

            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap" Text="Open"

                VerticalAlignment="Top" Margin="10.5,47,0,0"                
        FontSize="18.667"

                Foreground="{StaticResource StockCaptionBrush}"/>
            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap"

                Text="{Binding OpenPrice}"
                VerticalAlignment="Top" Margin="98.5,47,0,0"                
        FontSize="18.667"

                Foreground="{StaticResource                              
        StockDetailLightBlueForegroundBrush}"

                Width="111.5"/>
            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap" Text="Change"

                VerticalAlignment="Top" Margin="10.5,74,0,0"
                Foreground="{StaticResource StockCaptionBrush}"                
        FontSize="18.667"

                 RenderTransformOrigin=                    
        "0.666999995708466,0.455000013113022"/>

            <TextBlock HorizontalAlignment="Left"                
        TextWrapping="Wrap" Text="0.25%"

                VerticalAlignment="Top" Margin="98.5,74,0,0"                
        FontSize="18.667"

                Foreground="{StaticResource                              
        StockChangePositiveForegroundBrush}"                
        Width="111.5"/>

        </Grid>
    </Border>
</DataTemplate>
 

Now revisit the itemListView ListView control in the StockDetails.xaml file and set the SelectionMode property to None to disable the selection and ItemTemplate to the StockListTemplate data template we just created above to display each item. The related code snippet is shown below.

<ListView
    x:Name="itemListView"
    AutomationProperties.AutomationId="ItemsListView"
    AutomationProperties.Name="Items"
    TabIndex="1"
    Grid.Row="1"
    SelectionMode="None"
    Margin="-10,-10,0,0"
    Padding="120,0,0,60"
    ItemsSource=        "{Binding Source={StaticResource itemsViewSource}}"
    IsSwipeEnabled="False"
    SelectionChanged="ItemListView_SelectionChanged"
    ItemTemplate="{StaticResource StockListTemplate}" />
 

Next, to add the user control StockInfoView to this page you first need to declare it as shown below:

<common:LayoutAwarePage
    x:Name="pageRoot"
    . . ...
    xmlns:control="using:FinanceHub.View"
    mc:Ignorable="d">
 

Now locate the itemDetail ScrollViewer control and remove the following code.

<Image Grid.Row="1" Margin="0,0,20,0" Width="180" Height="180"     
        Source="{Binding Image}"

    Stretch="UniformToFill"/>
<StackPanel x:Name="itemDetailTitlePanel" Grid.Row="1"             
        Grid.Column="1">

    <TextBlock x:Name="itemTitle" Margin="0,-10,0,0"                 
        Text="{Binding Title}"

        Style="{StaticResource SubheaderTextStyle}"/>
    <TextBlock x:Name="itemSubtitle" Margin="0,0,0,20"        
        Text="{Binding Subtitle}"

        Style="{StaticResource TitleTextStyle}"/>
</StackPanel>
<TextBlock Grid.Row="2" Grid.ColumnSpan="2" Margin="0,20,0,0"    
        Text="{Binding Content}"

    Style="{StaticResource BodyTextStyle}"/>
 

Finally add StockInfoView to the itemDetail ScrollViewer to display the selected stock details as shown below.

<control:StockInfoView Grid.Row="1"></control:StockInfoView>

At this point you are all set with the StockDetails.xaml page. Now open the code-behind StockDetails.xaml.cs page and visit the existing LoadState method of this page and add MSFT stock related information to the ObservableCollection and assign this collection to DefaultViewModel’s Items key as shown below as we did for StocksPage.xaml.cs code-behind.

protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
    var collection = new ObservableCollection<Stock>();
    collection.Add(new Stock
    { Symbol = "MSFT",      
        OpenPrice = 30.05M,      
        Change = 0.25M,      
        CurrentPrice = 30.30M    
        });

    this.DefaultViewModel["Items"] = collection;
    ...
}

The remaining task is to implement a click event to the StocksPage so that upon clicking the stock from the StocksPage it navigates to the StockDetails page. In later chapters we will implement proper binding following MVVM design pattern.

Revisit StocksPage.xaml page itemGridView GridView control and set the IsItemClickEnabled attribute to True and set the ItemClick event to ClickedStock method as shown below.

<GridView
    x:Name="itemGridView"
    AutomationProperties.AutomationId="ItemsGridView"
    AutomationProperties.Name="Items"
    TabIndex="1"
    Grid.Row="1"
    SelectionMode ="None"
    IsItemClickEnabled="True"
    ItemClick="ClickedStock"
    Margin="0,-4,0,0"
    Padding="116,0,116,46"
    ItemsSource=        "{Binding Source={StaticResource itemsViewSource}}"
    ItemTemplate="{StaticResource StockTilesTemplate}"/>

Make similar changes to itemListView ListView control.

<ListView
    . . ..
    IsItemClickEnabled="True"
    ItemClick="ClickedStock"
    . . ..
    />
 

Now open code-behind StocksPage.xaml.cs file and implement ClickStock event that basically navigates to the StockDetails page.

void ClickedStock(object sender, ItemClickEventArgs e)
{
    this.Frame.Navigate(typeof(StockDetails));
}
 

You are all set to build and run the project. You should be in a position to click on the MSFT tile and get the details page as shown in Figure 2-10. If you click on the Back button you will go back to the stock main page displaying MSFT stock tile.

9781430249085_Fig02-10.jpg

Figure 2-10.  Stock Details Page

Adding Add Stock Flyout Control

There are only two remained items to build the final view are implementing Add and Remove stock flyout controls, which will be driven by the bottom app bar Add and Remove buttons.

image Note   Flyout controls provide traditional pop-up window functionality to Windows 8 applications. You usually display the content in the flyout control that you do not want to keep on the screen all the time. Even they are potentially used when you would like to implement pop-up window like user interface, you must follow guidelines of designing flyout controls to make your application qualified to be deployed in the Windows app store. You can get more details on this by visiting MSDN site – http://msdn.microsoft.com/en-us/library/windows/apps/hh465341.aspx.

Select View folder in the solution explorer and add a new blank UserControl type template with the name AddStockView.xaml. Remove the existing Grid control and instead add a StackPanel and add a caption, text box, and button that would allow the user to add a stock symbol to add it in the user’s watch list. The following is a complete code snippet.

<StackPanel     
       Background="{StaticResource AppBarBackgroundThemeBrush}">

    <TextBlock Text="Stock Symbol"        
       Style="{StaticResource CaptionTextStyle}" Margin="5"/>

    <TextBox x:Name="txtSymbol" HorizontalAlignment="Left"        
       TextWrapping="Wrap"

        VerticalAlignment="Top" Margin="5" Width="380"/>
    <Button Content="Add" HorizontalAlignment="Left"        
       VerticalAlignment="Top" Margin="5"/>

</StackPanel>

Adding Remove Stock Flyout Control

Select View folder in the Solution Explorer and add a new blank UserControl type template with the name RemoveStockView.xaml. Here we will put UI elements a ListView control that will display stocks, which can be selected using CheckBox control, and a button to remove selected one or more stocks:

<Grid Background="{StaticResource AppBarBackgroundThemeBrush}" >
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="42"/>
    </Grid.RowDefinitions>
    <ListView         Background="{StaticResource AppBarBackgroundThemeBrush}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <CheckBox/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button Content="Remove Selected"        
       HorizontalAlignment="Stretch"

        Grid.Row="1">    
</Button>

</Grid>

Integrating Flyout Controls with Bottom Application Bar

We will end the chapter by writing some C# code to integrate Add and Remove flyout controls with the bottom app bar Add and Remove buttons click events.

Creating UIHelper Dependency Class

To perform this task, first we need to create a generic method that can handle displaying of the requested flyout control as pop-up and manage when to dismiss it. Windows 8 application should support both virtual keyboard for touch-enabled devices and physical keyboards. Let’s get started.

First add a UIHelper class under the Common folder by selecting the folder and add a new empty class with the name UIHelper.cs.

Next add the following additional references to support our implementation.

using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

Now we will create a new method named ShowPopup with FrameworkElement parameter to determine the position of the flyout to display and UserControl parameter that determines which control to display. As explained earlier this method performs three main functions:

  1. Creates a new instance of the Popup class
  2. Defines position of the pop-up instance, enables light dismiss by setting Popup.IsLightDismissEnabled property to true (this will dismiss the pop-up as soon as user taps or clicks to any other area outside of the pop-up) and display the pop-up
  3. Handle virtual key board by using new event introduced in WinRT Windows.UI.ViewManagement.InputPane.GetForCurrentView().Showing

The following code snippet represents the ShowPopup method added to the UIHelper class.

public static Popup ShowPopup    
    (FrameworkElement source, UserControl control)

{
    Popup flyout = new Popup();
            
    var windowBounds = Window.Current.Bounds;
    var rootVisual = Window.Current.Content;

    //Define Flyout Control Position,    
    //Enable Light Dismiss and Display Popup

    GeneralTransform gt = source.TransformToVisual(rootVisual);

    var absolutePosition = gt.TransformPoint(new Point(0, 0));

    control.Measure(new        
    Size(Double.PositiveInfinity, double.PositiveInfinity));


    flyout.VerticalOffset =        
    windowBounds.Height - control.Height - 120;

    flyout.HorizontalOffset = (absolutePosition.X +        
    source.ActualWidth / 2) - control.Width / 2;

    flyout.IsLightDismissEnabled = true;

    flyout.Child = control;
    var transitions = new TransitionCollection();
    transitions.Add(new PopupThemeTransition()
        { FromHorizontalOffset = 0, FromVerticalOffset = 100 });
    flyout.ChildTransitions = transitions;
    flyout.IsOpen = true;
            
    // Handling the virtual keyboard
    int flyoutOffset = 0;
    Windows.UI.ViewManagement.InputPane.GetForCurrentView().        
    Showing += (s, args) =>

    {
        flyoutOffset = (int)args.OccludedRect.Height;
        flyout.VerticalOffset -= flyoutOffset;
    };
    
    Windows.UI.ViewManagement.InputPane.GetForCurrentView().        
    Hiding += (s, args) =>

    {
        flyout.VerticalOffset += flyoutOffset;
    };

    return flyout;
}

image Note   The credit for the above code of the ShowPopup method goes to author David Catuhe, who has blogged how to display flyout controls as a pop-up and handle virtual keyboard on the MSDN blog. For more details, visit http://blogs.msdn.com/b/eternalcoding/archive/2012/07/09/tips-and-tricks-for-c-metro-developers-handling-the-virtual-keyboard.aspx and http://blogs.msdn.com/b/eternalcoding/archive/2012/07/03/tips-and-tricks-for-c-metro-developers-the-flyout-control.aspx links.

Implementing Buttons Click Events to Display Pop-up

Finally it’s time to implement Click events for AddNewStock for the Add button and RemoveStock for the Remove button that we created with no business logic earlier in the chapter. Revisit MainPage.xaml.cs page and locate AddNewStock method.

First add the following three additional references to the code-behind to support our implementation.

using Windows.UI.Core;
using FinanceHub.Common;
using FinanceHub.View;

You can call CoreDispatcher.RunAsync on XAML UI element to run the event dispatcher and run as a task using the AsTask method that will return the results of the dispatched event asynchronously. For FinanceHub project we will call the UIHelper class ShowPopup method as an asynchronous operation as part of the Add and Remove button click events as shown below to display the related flyout controls. The following code snippet represents implementation of the Click events.

  
private void AddNewStock(object sender, RoutedEventArgs e)
{
    Dispatcher.RunAsync      
    (CoreDispatcherPriority.Normal, new DispatchedHandler(() =>

    {
        UIHelper.ShowPopup(this, new AddStockView());
    })).AsTask();
}

private void RemoveStock(object sender, RoutedEventArgs e)
{
    Dispatcher.RunAsync      
    (CoreDispatcherPriority.Normal, new DispatchedHandler(() =>

    {
        UIHelper.ShowPopup(this, new RemoveStockView());
    })).AsTask();
}

We have successfully completed the implementation of the View for the FinanceHub application. Now if you build your project and run it in the simulation mode you will see the project working as described earlier in this chapter including the bottom app bar with the functional add button (see Figure 2-11) and remove button (see Figure 2-12). You should also notice that the bottom app bar is available in both pages – stocks and stock details pages.

9781430249085_Fig02-11.jpg

Figure 2-11.  Bottom App Bar with Functional Add Stock Button

9781430249085_Fig02-12.jpg

Figure 2-12.  Bottom App Bar with Functional Remove Stock Button

Figure 2-13 shows the virtual keyboard enabling entry of the stock symbol in add stock flyout control.

9781430249085_Fig02-13.jpg

Figure 2-13.  Virtual Key Board Enabled for the Data Entry

Summary

We built Windows 8 application user interface following the hierarchical navigation pattern for the FinanceHub application. Along with building the user interface, we explored some of the key enhancements made in the XAML, such as use of using keyword to decorate the namespace in XAML and handling asynchronous operations as tasks, as well as some of the new properties introduced in WinRT. Visual Studio 2012 provides a simulator for debugging that would help test the different types of user interactions and different layout orientation models of the application.

Please note that we have hard-coded some values with the View definition for the complete end-to-end application demonstration purpose in this chapter. In the next two chapters we will remove the hard-coded value with the ViewModel and Model implementation separating out the View definition with the business logic and data source.

The next chapter defines the ViewModel of the application.

Do not forget to download the source code. Visit the Chapter 2 folder to view the source code that we developed in this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.104.160