Creating the Windows UI

Now we’re ready to tackle the Windows UI project. As specified in our prototype, our goal is to provide a single-page experience with the Windows project; we won’t need a details page—just a single main page that allows us to both list and edit details of an item in the list.

Because of the overlap in the XAML control library for Windows and for Windows Phone, we can quickly assemble much of the Windows user interface by copying what we have already implemented within the phone project.

The Master and Detail Regions

Open the MainPage.xaml file in the Windows project. Using the blank canvas of the design surface, we’ll first establish the separate regions for our list of meals and then detail edit/display controls. Within the existing grid, use the XAML designer to drop a column into the existing Grid control. (Refer to Chapters 21, “Building WPF Applications” and 23 for guidance on the XAML design surface.) We want the rightmost column to use auto width sizing, whereas the leftmost column will use star-sizing to occupy the remaining area of the screen.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

Due to slight differences in the way we want to present our data and inconsistencies between the ListView control between the two different platforms, we are going to use a GridView control instead of a ListView control here. This will enable the more standard horizontal display that you would typically see on a larger screened device.

Our GridView will share many attributes, however, with our phone UI. It will still use a two-line data template to display the meal information, and it will implement a Tapped event handler. Other than that, our bindings stay the same.

<GridView x:Name="GridViewMeals"
            Grid.Column="0"
            ItemsSource="{Binding Meals}"
            Tapped="GridViewMeals_Tapped" >
    <GridView.ItemTemplate>
            <DataTemplate>
                <Grid HorizontalAlignment="Stretch">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto"/>
                        <RowDefinition Height="auto"/>
                    </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="250" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding DateString}"
                            Grid.Row="0"
                            TextWrapping="Wrap"
                                HorizontalAlignment="Left"
                            Style="{StaticResource HeaderTextBlockStyle}"
                                FontSize="32"/>
                <TextBlock Text="{Binding Description}"
                        Grid.Row="1"
                        TextWrapping="Wrap"
                                HorizontalAlignment="Left"
                            Margin="12,-6,12,0"
                            Style="{StaticResource SubtitleTextBlockStyle}"
                            FontSize="14" />

                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
</GridView>

Over in the right column, add a Border control. This will be the parent control of our editing region of the screen (functioning as a sort of replacement for the Phone page that implemented this in the phone project). Set the background color to white.

<Border x:Name="DetailsPaneBorder"
        Width="450"
        Background="White"
        Grid.Column="1"
       >

Inside the Border parent container, you can go back to the phone project and copy and paste the entire Grid object that contained our editing controls. We’ll want to make some tweaks to account for the white background (setting border brushes to black, setting Foreground properties to black, and so on), but by and large the entire chunk of XAML can come over intact. We also want to copy over all our eventing code-behind for the plus and minus buttons.

The remaining item on the to-do list is fixing the data context for our XAML page. In the Phone world, we set the context of our main page to the main view model and then passed in the selected Meal object (using Navigate); then, in the detail page we set our data context from the passed-in Meal object within the OnNavigatedTo event. In the Windows project, we have only the single page. So there is no need to pass data around. But we still need to maintain two different data contexts: the main view model and the selected item. Within the MainPage.Xaml.cs code, place a member field to hold our Meal object.

private Meal _mealInstance;

public Meal MealInstance
{
    get { return _mealInstance; }
    set { _mealInstance = value; }

}

Then we can use the phone ListView’s Tapped code as a starting point. In the Tapped event in the Window's MainPage.xaml.cs, copy over the ListView Tapped code and remove the Navigate command. Then set the MealInstance object to the object pulled from the SelectedItem property.

//Cast selected item to Meal.
Meal MealInstance = (Meal)GridViewMeals.SelectedItem;
this.DetailsPaneBorder.DataContext = MealInstance;

With that final data context mapping in place, our app should be fully data aware and ready to run. To test the app, we will want to change the startup project to the Windows project and then make sure we have the Windows 8.1 simulator selected in the IDE (see Figure 24.17).

Image

FIGURE 24.17 Switching between the Windows Phone emulator and the Windows simulator.

Figure 24.18 shows our app now running in the Windows 8 simulator.

Image

FIGURE 24.18 The app running in the Windows 8.1 simulator.

The application is now fully functional, and ready to be deployed to either a Windows Phone 8.1 or Windows 8.1.

The Windows MainPage.xaml listing is provided in Listing 24.3, and the MainPage.xaml.cs listing is provided in Listing 24.4.

LISTING 24.3 The MainPage.xaml Code (Windows)


<Page
    x:Class="SplitTheTab.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SplitTheTab"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    >

    <Page.Resources>
        <local:DateTimeToDateTimeOffsetConverter
            x:Key="DateTimeToDateTimeOffsetConverter"/>
    </Page.Resources>
    <Page.BottomAppBar>
        <CommandBar x:Name="BottomAppBar1" Padding="10,0,10,0">
            <AppBarButton x:Name="AddButton"
                            Icon="Add"
                            Label="Add"
                            Click="AddButton_Click" />
        </CommandBar>
    </Page.BottomAppBar>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <GridView x:Name="GridViewMeals"
                    Grid.Column="0"
                    ItemsSource="{Binding Meals}"
                    Tapped="GridViewMeals_Tapped" >
            <GridView.ItemTemplate>
                    <DataTemplate>
                        <Grid HorizontalAlignment="Stretch">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto"/>
                                <RowDefinition Height="auto"/>
                            </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="250" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding DateString}"
                                    Grid.Row="0"
                                    TextWrapping="Wrap"
                                        HorizontalAlignment="Left"
                                    Style="{StaticResource HeaderTextBlockStyle}"
                                        FontSize="32"/>
                        <TextBlock Text="{Binding Description}"
                                Grid.Row="1"
                                TextWrapping="Wrap"
                                        HorizontalAlignment="Left"
                                    Margin="12,-6,12,0"
                                    Style="{StaticResource SubtitleTextBlockStyle}"
                                    FontSize="14" />

                        </Grid>
                    </DataTemplate>
                </GridView.ItemTemplate>
        </GridView>

        <Border x:Name="DetailsPaneBorder"
                Width="450"
                Background="White"
                Grid.Column="1"
                >
            <Grid Margin="20,0,20,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="15" />
                    <RowDefinition Height="Auto" />
                    <!-- Date -->
                    <RowDefinition Height="Auto" />
                    <!-- Sub Total -->
                    <RowDefinition Height="Auto" />
                    <!-- Tip -->
                    <RowDefinition />
                    <!-- Tip -->
                    <RowDefinition Height="Auto" />
                    <!-- Parties -->
                    <RowDefinition />
                    <!-- Parties -->
                    <RowDefinition />
                    <!-- Final totals -->
                </Grid.RowDefinitions>

                <StackPanel Grid.Row="0" Margin="12,17,0,28">
                    <TextBlock Text="SPLIT THE TAB"
                    Style="{StaticResource TitleTextBlockStyle}" />
                </StackPanel>

                <!-- Date -->
                <DatePicker x:Name="DatePickerMeal"
                            Header="Date:"
                        Grid.Column="0"
                            Grid.ColumnSpan="3"
                        Grid.Row="1"
                        VerticalAlignment="Center"
                        Foreground="Black"
                            BorderBrush="Black"
                        Date="{Binding Date,
                        Converter={StaticResource
                        DateTimeToDateTimeOffsetConverter}, Mode=TwoWay}"/>


                <!-- Sub Total -->
                <TextBlock Text="Total:"
                       Grid.Row="2"
                       Grid.Column="0"
                       Style="{StaticResource TitleTextBlockStyle}"
                       VerticalAlignment="Center"
                           Foreground="Black" />
                <TextBox x:Name="TextBoxTotal"
                     Grid.Column="1"
                     Grid.Row="2"
                     VerticalAlignment="Center"
                     Text="{Binding SubTotal}"
                         Foreground="Black" />

                <TextBlock Grid.Row="3"
                       Style="{StaticResource BodyTextBlockStyle}"
                       Text="Tip:"
                       Margin="0,15,0,0"
                           Foreground="Black" />


                <!-- Tip -->
                <Button x:Name="ButtonDownTip"
                    Grid.Row="4"
                    Grid.Column="0"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center"
                    FontSize="60"
                    Click="ButtonDownTip_Click"
                        Foreground="Black"
                        BorderBrush="Black"
                    >-


                </Button>
                <TextBlock x:Name="TextBlockTip"
                        Grid.Column="1" Grid.Row="4"
                        VerticalAlignment="Center"
                       HorizontalAlignment="Center"
                       Style="{StaticResource HeaderTextBlockStyle}"
                       Text="{Binding TipPercentString}"
                           Foreground="Black"/>

                <Button x:Name="ButtonUpTip"
                    Grid.Row="4"
                    Grid.Column="2"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="60"
                    Click="ButtonUpTip_Click"
                        Foreground="Black"
                        BorderBrush="Black"
                    >+
                </Button>


                <!-- Number of Parties -->
                <TextBlock Grid.Row="5"
                       Grid.ColumnSpan="2"
                       Grid.Column="0"
                       Style="{StaticResource BodyTextBlockStyle}"
                       Text="Number of Parties:"
                       Margin="0,15,0,0"
                           Foreground="Black" />

                <Button x:Name="ButtonDownParties"
                    Grid.Row="6"
                    Grid.Column="0"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center"
                    FontSize="60"
                    Click="ButtonDownParties_Click"
                        Foreground="Black"
                        BorderBrush="Black"
                    >-
                </Button>

                <TextBlock x:Name="TextBlockParties"
                       Grid.Column="1"
                       Grid.Row="6"
                       VerticalAlignment="Center"
                       HorizontalAlignment="Center"
                       Style="{StaticResource HeaderTextBlockStyle}"
                       Text="{Binding Parties}"
                           Foreground="Black"/>
                <Button x:Name="ButtonUpParties"
                    Grid.Row="6"
                    Grid.Column="2"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="60"
                    Click="ButtonUpParties_Click"
                        Foreground="Black"
                        BorderBrush="Black"
                    >+
                </Button>

                <Border Background="Gray"
                    Grid.Row="7"
                    Grid.Column="0"
                    Grid.ColumnSpan="3"
                    Margin="-20,15,-20,0"
                    >
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <TextBlock Text="Total"
                               Grid.Column="0"
                               Foreground="White"
                               VerticalAlignment="Bottom"
                               HorizontalAlignment="Center"
                               Style="{StaticResource HeaderTextBlockStyle}"
                               FontSize="24"
                               />
                        <TextBlock Text="Per Party"
                               Grid.Column="1"
                               Foreground="White"
                               VerticalAlignment="Bottom"
                               HorizontalAlignment="Center"
                               Style="{StaticResource HeaderTextBlockStyle}"
                               FontSize="24"
                               />
                        <TextBlock Text="{Binding GrandTotal}"
                               Grid.Column="0"
                               Grid.Row="1"
                               Foreground="White"
                               VerticalAlignment="Top"
                               HorizontalAlignment="Center"
                               Style="{StaticResource HeaderTextBlockStyle}"
                               FontSize="48"
                               />
                        <TextBlock Text="{Binding PerPartyGrandTotal}"
                               Grid.Column="1"
                               Grid.Row="1"
                               Foreground="White"
                               VerticalAlignment="Top"
                               HorizontalAlignment="Center"
                               Style="{StaticResource HeaderTextBlockStyle}"
                               FontSize="48"
                               />
                    </Grid>
                </Border>
            </Grid>
        </Border>

    </Grid>
</Page>


LISTING 24.4 The MainPage.xaml.cs Code (Windows)


using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using SplitTheTab.DataModel;

namespace SplitTheTab
{

    public sealed partial class MainPage : Page
    {
        private Meal _mealInstance;

        public Meal MealInstance
        {
            get { return _mealInstance; }
            set { _mealInstance = value; }

        }
        public MainPage()
        {
            this.InitializeComponent();

            this.NavigationCacheMode =
                NavigationCacheMode.Disabled;

            DataContext = App.ViewModel;
        }

        private void AddButton_Click(object sender,
            RoutedEventArgs e)
        {
            Meal newMeal = new Meal();
            newMeal.Date = DateTime.Today;
            newMeal.Parties = 1;
            newMeal.TipPercent = .20;
            newMeal.SubTotal = 50.00;

            App.ViewModel.Meals.Add(newMeal);
        }

        private void ButtonDownTip_Click(object sender,
            RoutedEventArgs e)
        {
            this.MealInstance.TipPercent =
                this.MealInstance.TipPercent - .05;
        }

        private void ButtonUpTip_Click(object sender,
            RoutedEventArgs e)
        {
            this.MealInstance.TipPercent =
                this.MealInstance.TipPercent + .05;
        }

        private void ButtonDownParties_Click(object sender,
            RoutedEventArgs e)
        {
            this.MealInstance.Parties =
                this.MealInstance.Parties - 1;
        }

        private void ButtonUpParties_Click(object sender,
            RoutedEventArgs e)
        {
            this.MealInstance.Parties =
                this.MealInstance.Parties + 1;
        }

        private void GridViewMeals_Tapped(object sender,
            TappedRoutedEventArgs e)
        {
            //Cast selected item to Meal.
            Meal MealInstance =
                (Meal)GridViewMeals.SelectedItem;
            this.DetailsPaneBorder.DataContext =
                MealInstance;
        }
    }
}


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

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