In Windows Store apps such as Hilo, there is one page
for each screen that a user can navigate
to. The app creates the first page on startup and then creates subsequent pages in response to
navigation requests.

You Will Learn

Applies To

Windows Runtime for Windows 8

Visual C++ component extensions (C++/CX)

XAML

Understanding the tools

For Hilo, we used Blend for Visual Studio and the Visual Studio XAML Designer to work with XAML, because these tools made it straightforward to quickly add and modify page layout. Blend was useful to initially define pages and controls; we used Visual Studio to "fine-tune" their appearances. These tools also enabled us to iterate quickly through design choices because they give immediate visual feedback.

In many cases, our UX designer was able to work in parallel with the developers because changing the visual appearance of a page does not affect its behavior.

We recommend that you use Visual Studio to work with the code-focused aspects of your app. Visual Studio is best suited for writing code, running, and debugging your app.

Tip

Visual Studio groups XAML design files with its code behind. From Solution Explorer, expand any .xaml file to see its backing .h and .cpp files.

We recommend that you use Blend for Visual Studio to work on the visual appearance of your app. You can use Blend to create pages and custom controls, change templates and styles, and create animations. Blend comes with minimal code-behind support.

When we built the app, we added each page to
the project by using the Add New Item dialog box in Visual
Studio. For the project template we used the Visual C++ / Windows Store / Grid App (XAML) template. Each page is a separate XAML tree in its own code
file.

The Grid App (XAML) template creates pages that are based on Visual Studio's LayoutAwarePage class, which provides navigation, state management, and view management.

In Hilo, we specialized the functionality of Visual Studio's LayoutAwarePage template class with the HiloPage class. This class customizes navigation behavior and state management for Hilo's view models. Hilo pages derive from HiloPage.

Creating pages in the designer view

Pages in Windows Store apps are user controls that support
navigation. Each page object represents content that can be
navigated to by the user. Pages contain other controls. Page
classes are laid out visually in the designer. All page classes are subtypes of the Windows::UI::Xaml::Page class. In Hilo, page classes also derive from the HiloPage class that in turn derives from the LayoutAwarePage class.

For example, here is what the image browser page looks like in the
Visual Studio designer.

Each page has an associated XAML file that is created by
Visual Studio, and a .h and .cpp file for page-related code written by
the app developer.

Visual Studio uses the partial keyword, which is part of the C++/CX language extensions, to split the declaration of a page class into several files. For example, for the hub page, the MainHubView class is split into four files.

MainHubView.xaml. This file contains the XAML markup that describe the page's controls and their visual layout.

MainHubView.g.h. This header file contains declarations that Visual Studio creates from the XAML source. You should not modify the contents of this file. (The "g" suffix in the file name stands for generated.)

MainHubView.xaml.h. This header contains declarations of member functions whose implementations you can customize. You can also add your own declarations of member functions and member variables to this file.

MainHubView.xaml.cpp. This is the code-behind file. Due to the use of the
Model-View-ViewModel (MVVM) pattern, this file only contains event handling code that delegates operations to the page's view model class, MainHubViewModel.

Tip Hilo uses the MVVM pattern that abstracts
the user interface for the application. With MVVM you rarely
need to customize the code-behind .cpp files. Instead, the
controls of the user interface are bound to properties of a
view model object. If page-related code is required, it
should be limited to conveying data to and from the page’s
view model object.

Establishing the data binding

Data
binding links each page to a view model class that is part of
the Hilo implementation. The view model class gives the page
access to the underlying app logic by using the conventions of
the MVVM pattern. For more info
see Using the MVVM pattern in this guide.

The data context of each page class in the Hilo app is set to the Hilo app’s ViewModelLocator class. The data
binding specifies the view model locator as a static
resource, which means the resource has previously been defined. In this case, the resource is a singleton instance of the
ViewModelLocator class.

Here is how the data context of the Hilo hub page is set with a data binding, taken from
the MainHubView.xaml file:

When the Windows Runtime creates a Hilo page, it binds to the
property specified in the
Path field of the data context. The property's get method is a method of Hilo’s ViewModelLocator
class, with the method creating a new view model object.
For example, the ViewModelLocator
class’s MainHubVM method creates an
instance of the MainHubViewModel
class.

Adding design time data

When you use a visual designer to create a data bound UI, you can display sample data to view styling results and layout sizes. To display data in the designer you must declare it in XAML. This is necessary because the designer parses the XAML for a page but does not run its code-behind. In Hilo, we wanted to display design time data in order to support the designer-developer workflow.

Sample data can be displayed at design time by declaring it in XAML by using the various data attributes from the designer XML namespace. This XML namespace is typically declared with a d: prefix.

Attributes with d: prefixes are then interpreted only at design time and are ignored at run time. For example, in a CollectionViewSource the d:Source attribute is used for design time sample data, and the Source attribute is used for run time data.

The d:DesignInstance attribute indicates that the design time source is a designer created instance based on the DesignTimeData type. The IsDesignTimeCreateable setting indicates that the designer will instantiate that type directly, which is necessary to display the sample data generated by the type constructor.

Creating the main hub page

The XAML UI framework provides a built-in navigation model that uses Frame and Page elements and works much like the navigation in a web browser. The Frame control hosts Pages, and has a navigation history that you can use to go back and forward through pages you've visited. You can also pass data between pages as you navigate.
In the Visual Studio project templates, a Frame named rootFrame is set as the content of the app window.

When the Hilo app starts up, the OnLaunched method of the Hilo::App class navigates to the app’s
hub page.

if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,// configuring the new page by passing required information as a navigation// parameter. See http://go.microsoft.com/fwlink/?LinkId=267278 for a walkthrough of how // Hilo creates pages and navigates to pages.if (!rootFrame->Navigate(TypeName(MainHubView::typeid)))
{
throw ref new FailureException((ref new LocalResourceLoader())->GetString("ErrorFailedToCreateInitialPage"));
}
}

This code shows how Hilo calls the Navigate method of a Windows::UI::Xaml::Controls::Frame
object to load content that is specified by the data type, in this case the MainHubView class. The Frame control helps maintain application
context. The code tests whether the frame object's Content property is null as a way of determining whether the app is resuming from a previous state or starting in its default navigation state. (For more info on resuming from previous states, see Handling suspend, resume, and activation in this guide.)

Navigating between pages

The LayoutAwarePage class provides methods that use frames to help the app navigate between pages. These are the GoHome, GoForward, and GoBack methods. Hilo calls these methods to initiate page navigation.

For example, the filmstrip control's Back button on the image view page invokes the GoBack method.

Direct navigation by the user is not the only possibility. For example, when the rotate image page loads, it locates the image in the file system. If the image is no longer there due to file system changes outside of the Hilo app, the rotate operation navigates back to the main hub page programmatically. Here's the code.

Supporting portrait, snap, and fill layouts

We designed Hilo to be viewed full-screen in the landscape orientation. Windows Store apps such as Hilo must adapt to different application view states, including both landscape and portrait orientations. Hilo supports FullScreenLandscape,
Filled,
FullScreenPortrait, and
Snapped layouts. Hilo uses the VisualState class to specify changes to the visual display to support each layout. The VisualStateManager class, used by the LayoutAwarePage class, manages states and the logic for transitioning between states for controls. For example, here is the XAML specification of the layout changes for the crop image page.

<VisualStateManager.VisualStateGroups><!-- Visual states reflect the application's view state --><VisualStateGroupx:Name="ApplicationViewStates"><VisualStatex:Name="FullScreenLandscape"/><VisualStatex:Name="Filled"/><VisualStatex:Name="FullScreenPortrait"><Storyboard><ObjectAnimationUsingKeyFramesStoryboard.TargetName="CancelButton"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Collapsed"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="CancelButtonNoLabel"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Visible"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="SaveButton"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Collapsed"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="SaveButtonNoLabel"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Visible"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualStatex:Name="Snapped"><Storyboard><ObjectAnimationUsingKeyFramesStoryboard.TargetName="CancelButton"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Collapsed"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="CancelButtonNoLabel"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Visible"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="SaveButton"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Collapsed"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="ResumeCropStackPanel"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Visible"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="CropCanvas"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Collapsed"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="CropImageGrid"Storyboard.TargetProperty="Margin"><DiscreteObjectKeyFrameKeyTime="0"Value="20,50,20,0"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFramesStoryboard.TargetName="PageTitle"Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrameKeyTime="0"Value="Visible"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState></VisualStateGroup></VisualStateManager.VisualStateGroups>

Note We typically set the Style property when we need to update multiple properties or when there is a defined style that does what we want. We often update individual properties directly when we only need to update one property. Although styles enable you to control multiple properties and also provide a consistent appearance throughout your app, providing too many can make your app difficult to maintain. Use styles only when it makes sense to do so. For more info about styling controls, see Quickstart: styling controls.

In most cases you can provide complete support for the app's view states by using XAML. In Hilo, there is only one place where we needed to change the C++ code to support layout. This is in the crop image view model, where the app adjusts the position of the crop overlay to match the new layout. To do this, the app provides a handler for the SizeChanged event.

When the image size changes as a result of a crop operation, the handler invokes the crop image view model's CalculateInitialCropOverlayPosition method, which makes the crop overlay fit the new layout. In addition, when the size of the page changes, such as when switching from the FullScreenLandscape view state to the Filled view state, the handler will again make the crop overlay fit the new layout.

Tip When you develop an app in Visual Studio, you can use the Simulator debugger to test layouts. To do this, press F5 and use the debugger tool bar to debug with the Simulator.