Книга: Professional Visual Basic 2012 and .NET 4.5
Назад: Chapter 12: XAML Essentials
Дальше: Chapter 14: Applications with ASP.NET, MVC, JavaScript and HTML

Chapter 13

Creating XAML Applications for Windows 8

What's in this chapter?

Differences in Windows 8 XAML from earlier XAML platforms

UX and UI conventions in Windows 8

New elements and new features in Windows 8 XAML

The Visual Studio 2012 designer for XAML

Application templates in Visual Studio 2012 for XAML apps

Implementing Live Tiles

Implementing contracts to work with Windows 8 charms

on the Download Code tab. The code is in the chapter 13 download and individually named according to the names throughout the chapter.

In chapter 12, you looked at XAML in a general way. That chapter covered capabilities and syntax that work exactly the name, except for minor details, on all three XAML platforms: WPF, Silverlight, and Windows 8 / WinRT. This chapter looks more deeply at XAML in the Windows 8 environment. The objective of the chapter is to build on general XAML expertise so that it can be applied to the creation of Windows 8 apps.

This chapter is aimed at those who have already absorbed enough about XAML to at least write simple applications on earlier XAML platforms. Chapter 12 was designed to assist those who have not yet used XAML in production on earlier platforms by presenting foundational XAML concepts. This chapter assumes that, at a minimum, the reader is familiar with all the concepts presented in Chapter 12.

For the benefit of those with more extensive experience in XAML, you'll begin by looking at a few significant ways in which Windows 8 XAML differs from that on earlier platforms. This section isn't intended to be comprehensive. Rather, it highlights differences that you are likely to encounter early in your attempts to create Windows 8 apps.

Then, you'll take up some of the user interface and user experience conventions you are expected to satisfy in Windows 8 apps. Some of these are advisory, but a number of them are required to place your app in the Windows Store for deployment. Chapter 20 covers how to use the Windows Store, including how to check your application to see if it satisfies necessary conventions.

Windows 8 contains a number of new visual elements, and some of them are designed to fit well within Windows 8 conventions. The chapter includes an overview of the most important of these new elements. You'll also need to look at several elements that existed in earlier XAML platforms, but have some special usage or significance in Windows 8 XAML, such as Frame and Popup.

The chapter also includes some discussion of the visual designer for XAML in Visual Studio 2012, particularly the associated Properties window, primarily to highlight differences from previous versions of Visual Studio.

Then, you'll get an overview of how to use the application templates for Windows 8 XAML apps offered by Visual Studio 2012. These templates are much more extensive than equivalents in earlier XAML platforms, and learning to use them is correspondingly harder.

Finally, you'll look at how your app fits into Windows 8 overall, including having your application expose an ActiveTile, and implementing a contract for search functionality.

shows all three of these elements in a screen shot of Internet Explorer, with the browser content removed for clarity. Each of them is brought into view by swiping from their respective side: right for charms, bottom for app bar, and top for navigation bar. If your app has both an app bar and a nav bar, bringing either one of them into view will cause the other one to also come into view.

The major elements that swipe in from the sides of a Windows 8 app are charms (on the right), the app bar (from the bottom), and the navigation bar (from the top).

13.1

The start bar is managed by the operating system. However, your application does interact with it in several key ways.

The Search charm at the top of the start bar is the new way Windows 8 handles search. It yields the sort of search results you would expect from previous versions of Windows, such as programs that match a search string. For the first time, though, Windows 8 search allows custom apps to contribute search results.

Your app also has the ability to share information with other apps via the Share charm. Interacting with the Windows 8 operating system via the Search and Share charms is done by implementing a contract in your app. You'll see how to do that later in the chapter. Your application can also participate with the Settings charm to put up app-specific settings.

Charms are always present; they're part of the OS. The other two bars are optional parts of your application. You get to choose whether your app will have an app bar, a navigation bar, or both. Windows controls when they appear, but you are responsible for all the functionality on them.

An app bar contains app-specific operations. In Internet Explorer's app bar, shown in , the app bar contains the address bar for entering a URL, and buttons such as Refresh (the arrowed circle) and Favorites (the pushpin).

For your own applications, common examples of app bar functionality would be an Add operation to add a new record to a list, or a Save operation to save changes. A typical line of business apps will usually have an app bar.

The nav bar is intended for use as a navigator inside an application. You can see a typical use of the nav bar in Internet Explorer, as shown in . The Windows 8 style version of Internet Explorer does not explicitly show browser tabs. The equivalent functionality is displayed in the nav bar, which shows open browser pages and allows the user to choose the active one, or to request a new tab via the button containing a plus sign. Your app might need a similar navigation pattern if it keeps more than one record open at a time.

App bars and nav bars are both implemented in your code with the AppBar element, and you'll see how to do that when you look at the new elements you'll be using routinely in Windows 8 apps. However, before you look at those elements, it's helpful for you to know some of the guidelines to which you must adhere when designing and developing Windows 8 apps.

. You should study those carefully.

To set the stage, though, here are a few of the most important concepts, particularly ones that are probably at significant variance from the applications you have written before.

Interaction between Your App and the Windows 8 OS

The earlier discussion of charms, app bar, and nav bar are part of the standard way apps are supposed to interact with the OS. So are contracts for Search and Share.

There are a number of other conventions in this general area of OS interaction. For example, your application should not have a Close button, or any equivalent functionality. A standard gesture is available to close an app. It can be done with either touch or mouse; while an app is open, start at the top of the screen, and drag toward the middle until you see the app shrink and center on the screen. Then continue dragging to the bottom, and the app will be closed.

Chromeless Apps

Windows 8 apps are “chromeless.” That simply means none of the border cosmetics in earlier versions of Windows are present. Windows 8 apps have no sizable borders, no title bar, and none of the buttons you associate with the title bar. The OS expects the user to focus most of the time on one application, and thus it is optimized to show one application on a clean surface.

The screens in an app are commonly called views. In older technologies, it was common for views to have buttons for operations such as Save. Views in Windows 8 apps should not have such buttons on the main view, because it's easy for them to be activated inadvertently during a touch operation. The app bar is the preferred location for any such buttons needed by your app, because it comes into view only when the user does the proper gesture to request it.

Snapped Views

Multiple apps are shown only via a “snapped” view, with a limit of two apps at a time. In a snapped view, one app gets a reduced slice of the screen that is 320 pixels wide. This view can be on either side of the screen. The rest of the screen, which is significantly bigger, hosts the other app. An example screen with a snapped view is shown in .

Only two apps can share the Windows 8 screen at a time. One app is in a “snapped view” which is 320 pixels wide. The other app takes up the remaining screen space.

13.2

Windows 8 furnishes a mouse or touch gesture to make an app snapped. It's similar to the close gesture just discussed. With an app open in full screen, drag from the middle top until the app shrinks and centers in the screen. Then, instead of dragging to the bottom as you do with a close, drag to either side to make the app snap to that side.

To pass certification for placement in the Windows Store, your app is required to support a snapped view. It is up to you to design an appropriate view for when your app is snapped. In the case of the Music player shown in , the designer decided to show a sparse vertical view of the music being played, with some minimal controls. Some applications merely place status information in the snapped view.

Typeface and Font Guidelines

Windows 8 has a standard set of typefaces you are supposed to use in your apps. The most commonly used typeface is Segoe, an elegant sans serif typeface. It's nicer than the typical fonts such as Arial that many applications use today, and there's no reason to change it for line-of-business applications.

If you application has a lot of content to be read and/or edited, you are expected to take advantage of two other standard typefaces. For parts of an application where the user would be reading and editing, such a detailed product description or an email message, you should use Calibri. For apps that are primarily intended for reading, such as a newsreader app, content should be in Cambria.

The Windows 8 UX guidelines include recommendations about using particular font sizes and weights. You should become familiar with those and use them unless you have a very good reason not to do so.

Sizing and Layout of Visual Elements in an App

In earlier XAML platforms, you were on your own to decide sizing of elements. For apps in Windows XAML, however, you need to try to be consistent with the conventions for screen layout in Windows 8 apps.

Most sizing of items, such as data items in a list, should be based on the “grid system,” in which blocks of 20∞20 pixels for the basis for a number of larger sizes. Spacer areas are often 10 pixels wide or high. The built-in application templates can give you a push in that direction. They include some sample data templates that are sized according to the Windows 8 guidelines. You'll see the list of templates and sizes in the section on Windows 8 Application Templates below.

You also need to provide appropriately sized header areas and margins. These can vary to suit the type of touch navigation that is being used.

The UX guidelines give precise details and recommendations, but you'll look at one typical case. Suppose you wanted a view with a list of items on the left side of the screen, and you intended the list to scroll vertically. Such a view might provide a header area that was 100 pixels high, and provide a margin on the left of 120 pixels. In fact, you will use those numbers in the first ListView example later in the chapter, because it does vertical scrolling.

The topics above only furnish a starting point for user experience guidelines. You should invest time to become familiar with the entire set. Remember, some of the user experience guidelines are required for your app to be certified in the Windows Store, which is discussed in Chapter 20.

shows an app bar with such an arrangement.

An app bar appears on a swipe from the bottom of the screen. Item-specific buttons should be on the left, and general app action buttons on the right.

13.3

One XAML layout that will give you such an arrangement is to make the root element inside the app bar a Grid with two equal columns. Place a horizontal StackPanel in each column of the Grid, with the one in the first column aligned to the left, and the one in the second column aligned to the right. Then put appropriate buttons in each StackPanel.

The XAML for the app bar shown in follows this pattern, and looks like this (code file: BottomAppBar.xaml):

<Page.BottomAppBar>      <AppBar>          <Grid>              <Grid.ColumnDefinitions>                  <ColumnDefinition />                  <ColumnDefinition />              </Grid.ColumnDefinitions>              <!--StackPanel on the left for item-specific buttons-->              <StackPanel Orientation="Horizontal"                          HorizontalAlignment="Left">                  <Button Name="AppBarEditButton"                           Style="{StaticResource EditAppBarButtonStyle}"                      />                  <Button Name="AppBarDeleteButton"                           Style="{StaticResource RemoveAppBarButtonStyle}"                  />              </StackPanel>             <!--StackPanel on the right for general app buttons-->              <StackPanel Orientation="Horizontal" Grid.Column="1"                          HorizontalAlignment="Right">                  <Button Name="AppBarAddButton"                       Style="{StaticResource AddAppBarButtonStyle}"                          />                  <Button Name="AppBarRefreshButton"                           Style="{StaticResource RefreshAppBarButtonStyle}"                  />                  <Button Name="AppBarHelpButton"                           Style="{StaticResource HelpAppBarButtonStyle}"                          />              </StackPanel>          </Grid>      </AppBar>  </Page.BottomAppBar>  

Notice that the buttons in the app bar are all created using styles. Even the icon inside each button is part of the style.

It isn't necessary for you to write the styles needed for common app bar buttons. A set of 62 styles is available to you in a XAML file called StandardStyles.xaml. However, they are commented out in the file, because it doesn't make sense to load all of them if they are not needed. So you must uncomment the ones you need. For the sample, all the styles referred to in the XAML snippet above were uncommented.

App bars can contain a lot more than buttons, and can be as complex as needed for your app. They don't have a specific size either—an app bar will be automatically sized to hold whatever is placed in it. All the layout techniques covered in Chapter 12 are at your disposal to create a richer app bar, and you can place any elements you need in the app bar.

Constructing a Top Nav Bar

The process for creating a nav bar is the same as that for creating an app bar, except that you use the Page.TopAppBar property instead of Page.BottomAppBar. However, where typical app bars often generally look the same, there is no consistent layout for a nav bar.

A common use of a nav bar is to allow the user to navigate to open items. In this case, some kind of ItemControl is often used to hold the available items in a horizontal orientation. Here is an example, with some fudged-up items for demonstration. This example uses a ListView to hold several items, and the ListView control will be covered in detail later in this section (code file: TopAppBar.xaml):

<Page.TopAppBar>      <AppBar>          <StackPanel Orientation="Horizontal" Height="250">              <ListView Margin="20">                  <ListView.ItemsPanel>                      <ItemsPanelTemplate>                          <VirtualizingStackPanel Orientation="Horizontal" />                      </ItemsPanelTemplate>                  </ListView.ItemsPanel>                  <ListViewItem>                      <Border Width="120" Height="160"                               BorderBrush="LightGray"                               Background="DarkGray" BorderThickness="3">                          <TextBlock Margin="4" FontSize="20"                                      Text="An active item"                                      TextWrapping="Wrap" />                      </Border>                  </ListViewItem>                  <ListViewItem>                      <Border Width="120" Height="160"                               BorderBrush="LightGray"                               Background="DarkGray" BorderThickness="3">                          <TextBlock Margin="4" FontSize="20"                                      Text="The second active item"                                      TextWrapping="Wrap" />                      </Border>                  </ListViewItem>                  <ListViewItem>                      <Border Width="120" Height="160"                               BorderBrush="LightGray"                               Background="DarkGray"  BorderThickness="3">                          <TextBlock Margin="4" FontSize="20"                                      Text="Another active item"                                      TextWrapping="Wrap" />                      </Border>                  </ListViewItem>                  <ListViewItem>                      <Border Width="120" Height="160"                               BorderBrush="LightGray"                               Background="DarkGray" BorderThickness="3">                          <TextBlock Margin="4" FontSize="20"                                      Text="Yet another active item"                                      TextWrapping="Wrap" />                      </Border>                  </ListViewItem>                  <ListViewItem>                      <Border Width="120" Height="160"                               BorderBrush="LightGray"                               Background="DarkGray" BorderThickness="3">                          <TextBlock Margin="4" FontSize="20"                                      Text="The last active item"                                      TextWrapping="Wrap" />                      </Border>                  </ListViewItem>              </ListView>              <Button Margin="20" Content="A button for something" FontSize="20" />          </StackPanel>      </AppBar>  </Page.TopAppBar>  

The resulting nav bar is shown in , with the second item selected by the user. Note that since the app now has both an app bar and nav bar, both are shown when the top nav bar is brought into view.

A nav bar appears on a swipe from the top of the screen. The app bar (bottom) also appears when the nav bar is called into view.

13.4

ListView, GridView, and FlipView Controls

In earlier XAML platforms, the ListBox was a commonly used control to show lists of data items. The ListBox is one of a general category of XAML controls called ItemControls. As seen in Chapter 12, ItemControls have an ItemsSource property to point to the list of data items to be displayed, and an ItemTemplate property to point to a data template used to format individual items for display.

In Windows 8, ListBox is used less, and its niche is occupied by two other ItemControls: GridView and ListView. ListView is very much like a ListBox, but has some added capabilities. GridView offers a different arrangement of the displayed items. Let's look at ListView and GridView individually, with visual examples to show how they work. These examples will also be used to show some of the conventions and styles you'll typically use in a Windows 8 app.

FlipView is another ItemsControl that is new to Windows 8. As an ItemsControl, it shares a fair amount of syntax with ListView and GridView, but the navigation between items is completely new. FlipView allows one item at a time to take over the entire control, and supports touch and mouse gestures to “flip” between the data items.

Sample Data for Examples of ItemControls

Before you can look at the new ItemControls in Windows 8 XAML, there's a bit of prep work required. Seeing these ItemControls in operation requires sample data, so you need to construct it.

The sample data is constructed by first creating data object classes, and then declaring some instances of those classes in XAML.

About Data Models

There are a wide variety of ways to access and package data in Visual Basic. This chapter will not go into detail about that; Chapters 9, 10, and 11 discuss some of the details.

Since this chapter is not primarily about data, the data models used in examples are about as simple as it is possible to make them. The overall schema is an expansion of the Customer record model used in Chapter 12. It adds contact records, and each Customer includes a collection of contacts.

The classes used will include:

These models are simpler than the sample data models used in the application templates in Windows 8 XAML. Those models add additional features to support a code organization pattern that some developers like to use in their data models, which is called Model-View-ViewModel, commonly abbreviated MVVM. Since MVVM isn't required to do Windows 8 apps, and since there are many resources that go into intricate detail on MVVM, it is not discussed further in this chapter.

Technical Notes for the Customer/Contact Sample Data Model

The classes for Customer and Contact records, and their respective collection classes, must satisfy a couple of important capabilities to work well in Windows 8 XAML. The data records (Customer and Contact) must have property change notification. That simply means they implement an interface called INotifyPropertyChanged. That allows properties to raise an event called PropertyChanged, which is monitored by the data binding system so that bindings are updated when properties are changed. Your implementation of INotifyPropertyChanged will be minimal, because best practices for data classes are beyond the scope of this chapter.

The collection classes must be of a type that has events when items are added to or removed from the collection. The class used for that will be familiar to experienced XAML developers. It is a generic collection class called ObservableCollection(of T).

The code for the data model is included in the code download for the chapter. However, for reference, the code listings are included here as well.

Here are code listings for the Contact and Contacts classes (code file: ContactClasses.vb):

Public Class Contact      Implements INotifyPropertyChanged        Private _ContactName As String      Public Property ContactName() As String          Get              Return _ContactName          End Get          Set(ByVal value As String)              If _ContactName <> value Then                  _ContactName = value                  NotifyPropertyChanged("ContactName")              End If          End Set      End Property        Private _Phone As String      Public Property Phone() As String          Get              Return _Phone          End Get          Set(ByVal value As String)              If _Phone <> value Then                  _Phone = value                  NotifyPropertyChanged("Phone")              End If          End Set      End Property        Public Event PropertyChanged(ByVal sender As Object,              ByVal e As System.ComponentModel.PropertyChangedEventArgs)              Implements              System.ComponentModel.INotifyPropertyChanged.PropertyChanged        Private Sub NotifyPropertyChanged(ByVal PropertyName As String)          Dim eNew As New PropertyChangedEventArgs(PropertyName)          RaiseEvent PropertyChanged(Me, eNew)      End Sub    End Class    Public Class Contacts      Inherits ObservableCollection(Of Contact)    End Class  

Here are code listings for the Customer and Customers classes (code file: CustomerClasses.vb):

Public Class Customer      Implements INotifyPropertyChanged        Public Sub New()          _Contacts = New Contacts      End Sub        Private _CustomerName As String      Public Property CustomerName() As String          Get              Return _CustomerName          End Get          Set(ByVal value As String)              If _CustomerName <> value Then                  _CustomerName = value                  NotifyPropertyChanged("Name")              End If          End Set      End Property        Public Event PropertyChanged(ByVal sender As Object,           ByVal e As System.ComponentModel.PropertyChangedEventArgs)           Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged        Private Sub NotifyPropertyChanged(ByVal PropertyName As String)          Dim eNew As New PropertyChangedEventArgs(PropertyName)          RaiseEvent PropertyChanged(Me, eNew)      End Sub        Private _Active As Boolean      Public Property Active() As Boolean          Get              Return _Active          End Get          Set(ByVal value As Boolean)              If _Active <> value Then                  _Active = value                  NotifyPropertyChanged("Active")              End If          End Set      End Property        Private _Contacts As Contacts      Public Property Contacts() As Contacts          Get              Return _Contacts          End Get          Set(ByVal value As Contacts)              If _Contacts IsNot value Then                  _Contacts = value                  NotifyPropertyChanged("ContactName")              End If          End Set      End Property        Private _Phone As String      Public Property Phone() As String          Get              Return _Phone          End Get          Set(ByVal value As String)              If _Phone <> value Then                  _Phone = value                  NotifyPropertyChanged("Phone")              End If          End Set      End Property        Private _Logo As String      Public Property Logo() As String          Get              Return _Logo          End Get          Set(ByVal value As String)              If _Logo <> value Then                  _Logo = value                  NotifyPropertyChanged("Logo")              End If          End Set      End Property    End Class    Public Class Customers      Inherits ObservableCollection(Of Customer)    End Class  

Finally, here is the XAML that is used to declare a set of five customer objects, each with a Contacts collection. This resource, named CustomerList, is then used as the ItemsSource for various ItemControls in the examples (code file: SampleCustomerList.xaml):

<local:Customers x:Key="CustomerList">      <local:Customer CustomerName="BigBux, Inc."                       Active="True"                      Phone="223-555-1234"                       Logo="http://billyhollis.com/Logos/BigBuxLogo.png" >          <local:Customer.Contacts>              <local:Contact ContactName="Sherlock Holmes" Phone="212-555-1234" />              <local:Contact ContactName="John Watson" Phone="212-555-3456" />              <local:Contact ContactName="Mycroft Holmes" Phone="212-555-6789" />          </local:Customer.Contacts>      </local:Customer>      <local:Customer CustomerName="SmallPotatoes, Ltd."                       Active="False"                       Phone="212-555-1234"                       Logo="http://billyhollis.com/Logos/SmallPotatoesLogo.png">          <local:Customer.Contacts>              <local:Contact ContactName="Oliver Twist" Phone="414-555-1234" />          </local:Customer.Contacts>        </local:Customer>      <local:Customer CustomerName="Medium Enterprises, Inc."                       Active="True"                       Phone="313-555-1234"                       Logo="http://billyhollis.com/Logos/MediumEnterprisesLogo.png" >          <local:Customer.Contacts>              <local:Contact ContactName="Elizabeth Bennet" Phone="313-555-1234" />              <local:Contact ContactName="John Darcy" Phone="313-555-3456" />              <local:Contact ContactName="Charlotte Lucas" Phone="313-555-6789" />          </local:Customer.Contacts>        </local:Customer>      <local:Customer CustomerName="Globe Theatre"                       Active="False"                       Phone="515-555-1234"                       Logo="http://billyhollis.com/Logos/GlobeTheatreLogo.png">          <local:Customer.Contacts>              <local:Contact ContactName="Romeo Montague" Phone="505-555-1234" />              <local:Contact ContactName="Othello Jones" Phone="505-555-3456" />              <local:Contact ContactName="Juliet Capulet" Phone="505-555-6789" />          </local:Customer.Contacts>        </local:Customer>      <local:Customer CustomerName="Global Traders"                   Active="True"                   Phone="616-555-1234"                   Logo="http://billyhollis.com/Logos/GlobalTradersLogo.png">          <local:Customer.Contacts>              <local:Contact ContactName="Silas Marner" Phone="707-555-1234" />          </local:Customer.Contacts>        </local:Customer>  </local:Customers>  

For all the examples in this section, you should assume that the four classes above are part of the project, and that the XAML declaring CustomerList has been placed in the Resources section of App.xaml.

ListView

ListView is so similar to ListBox that in many cases you can easily change your old ListBox XAML to use a ListView instead. Unless you're doing something fancy with the ListBox, you can just change the tag from ListBox to ListView, and the XAML will work.

The main advantage of ListView over ListBox is that is has better touch functionality, and works more transparently with standard Windows 8 gestures. For example, if you are swiping through a list (which is often called panning), then when you raise your finger the list shows inertia. It continues moving while it decelerates to a stop. This generates a more natural interaction pattern, because that's the way things act in the real world.

Using the sample customer data defined earlier, let's look at the XAML for a ListView example, including a data template that will format Customer data records. To construct the example, just create a new Blank App and replace the Grid element in MainPage with the following XAML (code file:CustomerDataTemplate.xaml):

<Page.Resources>      <DataTemplate x:Key="Standard250x250ItemTemplate">          <Grid HorizontalAlignment="Left" Width="250" Height="250"                 Background="{StaticResource   ListViewItemPlaceholderBackgroundThemeBrush}">                <StackPanel Margin="4" VerticalAlignment="Top"                      Background="{StaticResource   ListViewItemOverlayBackgroundThemeBrush}">                  <TextBlock LineHeight="28" FontSize="24"                              Text="{Binding CustomerName}"                      Foreground="{StaticResource   ListViewItemOverlayForegroundThemeBrush}"                                                   Style="{StaticResource TitleTextStyle}" Margin="15,0,15,0"/>                  <TextBlock LineHeight="24" FontSize="18" Text="{Binding Phone}"                      Foreground="{StaticResource   ListViewItemOverlayForegroundThemeBrush}"                                                   Style="{StaticResource TitleTextStyle}" Margin="15,0,15,0"/>                  <Image Source="{Binding Logo}" MaxWidth="120"                          HorizontalAlignment="Center" Margin="20"/>              </StackPanel>          </Grid>      </DataTemplate>        </Page.Resources>    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">      <Grid.RowDefinitions>          <RowDefinition Height="140"/>          <RowDefinition Height="*"/>      </Grid.RowDefinitions>      <TextBlock x:Name="pageTitle" Grid.Column="1" Text="ListView Example"                  Margin="120,0,0,0" Style="{StaticResource PageHeaderTextStyle}"/>      <ListView Grid.Row="1" Margin="120,0,0,0"                 ItemTemplate="{StaticResource Standard250x250ItemTemplate}"                ItemsSource="{StaticResource CustomerList}" />  </Grid>  

The data template is one of the standard sizes used in Windows 8, and the resource name indicates that. In fact, it was created by copying the resource of the same name out of StandardStyles.xaml.

Notice that the layout of the Page containing the ListView satisfies simple Windows 8 conventions. The top header area, which often contains the application name, is 140 pixels high, and both the header area and the ListView have a left margin of 120 pixels. For vertically scrolling content, the bottom margin is often zero, and the ListView does vertical scrolling by default (though it has an ItemsPanel property to change that, just as a ListBox does).

If this XAML is placed in a Blank App project that has your earlier Customer/Contact data model incorporated, then the running application will look like .

A ListView provides a touch-friendly, vertically scrolling list of data items. The second item has been selected by the user.

13.5

Just as the items in a ListBox are ListBoxItem instances, the items in a ListView are ListViewItem instances. These can be created manually instead of being manufactured from data, as the example in above showed. This is rarely used for line-of-business applications.

GridView

GridView is very similar to ListView with the following exceptions:

The syntax is so similar that if you simply change the ListView tag to a GridView tag in the XAML shown above, it will work fine, and you'll get a running program that looks like .

A GridView provides a touch-friendly, horizontally scrolling list of data items, wrapped into columns. The third item has been selected by the user.

13.6

Like ListView, GridView is nicely optimized for touch interaction. In fact, both ListView and GridView inherit from a class named ListViewBase, where much of that touch interaction functionality is implemented.

Grouping in ListView and GridView

Some data models include data items grouped by some factor, usually a property value. For example, Customer data items might be grouped by the state in which the customer is located, or by whether or not the Customer is active.

If you are familiar with XAML in WPF, you may know about grouping in the ListBox control, using a CollectionViewSource to obtain a collection view, and then altering its GroupDescriptions property. Grouping is also available in the ListView and GridView controls in Windows 8, and the grouping still involves a CollectionViewSource. However, the underlying mechanisms are different. Windows 8 grouping depends on a data model that implement groups, instead of having groups automatically created via a CollectionView.

To see grouping in action in a GridView, you'll need to do some changes to your default data model. The CustomerGroups class will serve as the container of your groups of customer objects, and it will hold a collection of instances of the Customers class.

You've already seen the Customers class, and how it holds a collection of Customer objects. However, it does need one additional property to describe the particular group of Customers in an instance. That simply means that the following line needs to be added to the Customers class:

Public Property GroupName As String  

Here is the rather simple code for the CustomerGroups class that holds a collection of instances of Customers collections:

Public Class CustomerGroups      Inherits ObservableCollection(Of Customers)    End Class  

With these data classes in place, you change the way your sample data is declared to create a sample data source holding groups of customers instead of just customer objects. Here is that XAML, which is placed in the App.xaml resources area (code file: GroupedCustomers.xaml):

<local:CustomerGroups x:Key="GroupedCustomers">      <local:Customers GroupName="Active Customers">          <local:Customer CustomerName="BigBux, Inc."                   Active="True" Special="True"                  Phone="223-555-1234"                   Logo=" http://billyhollis.com/Logos/BigBuxLogo.png" >              <local:Customer.Contacts>                  <local:Contact ContactName="Sherlock Holmes"                                  Phone="212-555-1234" />                  <local:Contact ContactName="John Watson" Phone="212-555-3456" />                  <local:Contact ContactName="Mycroft Holmes" Phone="212-555-6789" />              </local:Customer.Contacts>          </local:Customer>          <local:Customer CustomerName="Medium Enterprises, Inc."                   Active="True"                   Phone="313-555-1234"                   Logo=" http://billyhollis.com/Logos/MediumEnterprisesLogo.png" >              <local:Customer.Contacts>                  <local:Contact ContactName="Elizabeth Bennet"                                  Phone="313-555-1234" />                  <local:Contact ContactName="John Darcy" Phone="313-555-3456" />                  <local:Contact ContactName="Charlotte Lucas"                                  Phone="313-555-6789" />              </local:Customer.Contacts>            </local:Customer>          <local:Customer CustomerName="Global Traders"               Active="True"               Phone="616-555-1234"               Logo=" http://billyhollis.com/Logos/GlobalTradersLogo.png">              <local:Customer.Contacts>                  <local:Contact ContactName="Silas Marner" Phone="707-555-1234" />              </local:Customer.Contacts>            </local:Customer>      </local:Customers>        <local:Customers GroupName="Inactive Customers">          <local:Customer CustomerName="SmallPotatoes, Ltd."                   Active="False"                   Phone="212-555-1234"                   Logo=" http://billyhollis.com/Logos/SmallPotatoesLogo.png">              <local:Customer.Contacts>                  <local:Contact ContactName="Oliver Twist" Phone="414-555-1234" />              </local:Customer.Contacts>            </local:Customer>          <local:Customer CustomerName="Globe Theatre"                   Active="False"                   Phone="515-555-1234"                   Logo=" http://billyhollis.com/Logos/GlobeTheatreLogo.png">              <local:Customer.Contacts>                  <local:Contact ContactName="Romeo Montague" Phone="505-555-1234" />                  <local:Contact ContactName="Othello Jones" Phone="505-555-3456" />                  <local:Contact ContactName="Juliet Capulet" Phone="505-555-6789" />              </local:Customer.Contacts>            </local:Customer>      </local:Customers>    </local:CustomerGroups>  

With this sample data, a CollectionViewSource can be declared to use in your GridView. It is declared in the Resources for the Page, and looks like this:

<CollectionViewSource x:Key="GroupedCustomersSource"                    Source="{StaticResource GroupedCustomers}"                    IsSourceGrouped="True"  />  

To make the GridView display groups, two changes are essential. First, the ItemsSource must be changed to become the CollectionViewSource that holds the groups instead of being a simple list of customers. Second, the GridView must have a GroupStyle defined, so that the GridView knows how to display the head for groups and, optionally, how data items in groups will be arranged. Taking all that into account, the GridView XAML definition needs to look something like this (code file: GridViewExample.xaml):

<GridView Margin="120,133,0,7" Name="MainGridView"                     ItemsSource="{Binding Source={StaticResource   GroupedCustomersSource}}"                   ItemTemplate="{StaticResource Standard250x250ItemTemplate}"                    Grid.RowSpan="2" >      <GridView.GroupStyle>          <GroupStyle>              <GroupStyle.HeaderTemplate>                  <DataTemplate>                      <TextBlock Text="{Binding GroupName}"                                  Style="{StaticResource SubheaderTextStyle}"                                  Margin="5,15" />                  </DataTemplate>              </GroupStyle.HeaderTemplate>              <GroupStyle.Panel>                  <ItemsPanelTemplate>                      <VariableSizedWrapGrid Orientation="Vertical"   Margin="0,0,80,0"/>                  </ItemsPanelTemplate>              </GroupStyle.Panel>          </GroupStyle>      </GridView.GroupStyle>        </GridView>  

If you make these changes to the earlier GridView example and run the program, you'll get a sample screen that looks something like .

A GridView with grouped customer items

13.7

The amount of work involved to create a data model for a grouped data source is not trivial, but if your users need to look at data in groups, GridView and ListView can easily show them. In many cases, you will find it easier to use LINQ in code to produce your groups.

FlipView

FlipView is another touch-optimized ItemControl. However, while the XAML FlipView strongly resembles that for ListView or GridView, its navigation/interaction pattern is quite distinct from other ItemControls.

Like all ItemControls, FlipView includes a collection of items in a list. The item type is FlipViewItem.

However, unlike all the other ItemControls you've likely seen, FlipView only shows one item at a time. The entire area of the FlipView is available to show a data item. The FlipView then offers gestures to move between items, which is sometimes called “flipping.”

The touch gesture to flip between items is a horizontal swipe. A swipe to the left brings up the next item, while a swipe to the right goes back to the previous item in the list.

To allow equivalent interaction with a mouse, when a mouse moves over a FlipView, navigation buttons fade in on the sides to provide a place to click and navigate. A button is present only if navigation is possible in that direction. That is, when you are on the last item in the list, the button on the right does not appear. Likewise, the left button is absent in you are on the first item in the list.

If you would like the items to be a “ring” in which navigating from the last item loops back to the first item, then set the TabNavigation property to “Cycle.” If you are familiar with Windows Phone development, you may have used the Panorama control. A FlipView with TabNavigation set to Cycle provides similar functionality, though the small part of the next record that shows on the right side in the Panorama is not present.

In the first ListView XAML example, if the tags are changed to a FlipView, then you'll see a screen similar to . Since the data template wasn't changed, the single data item shown is much smaller than the screen, and isn't centered. In a real app, you'll rarely use a FlipView unless you need room for a larger data item, and centering the item is almost always appropriate.

A FlipView showing the first record in your sample data

13.8

Touch gestures and mouse gestures are active for navigation at this point. If you move the mouse over the FlipView, the navigation buttons will show, as in .

A FlipView showing the second record in your sample data, after a mouse has been moved over it. Note the navigation buttons to the left and right.

13.9

shows that the navigation buttons are inside the FlipView, and will be on top of a data item if necessary. In many cases, when using a FlipView, you will want the FlipView control to be as wide as the whole view, and set up the data template to be centered and to allow space on the sides for the navigation buttons to appear.

DataTemplateSelector

In Chapter 12, data templates were discussed in detail. In all those examples, an ItemsControl used a data template by setting the ItemTemplate property to a data template.

WPF developers may be familiar with a different way to determine the data templates used in an ItemsControl—a data template selector. This is an object that inherits from the DataTemplateSelector class, and contains logic to examine each data item and decide which template should be used to render that item.

GridView, ListView, and FlipView can all use a data template selector in Windows 8. The way the class is constructed is slightly different from WPF. Instead of overriding the SelectTemplate method, as in WPF, the SelectTemplateCore method is overridden instead.

The class for a data template selector usually has some properties to hold the templates that are being used to render various data items. In your example below, you will construct a CustomerDataTemplateSelector, and give it properties for ActiveCustomerTemplate and InactiveCustomerTemplate.

Typically, an instance of the DataTemplateSelector is created in a project as a resource, and the ItemTemplateSelector of a GridView, ListView, or FlipView is set to that resource. For an example, you'll modify the earlier GridView example to add the data template selector.

The code download for the chapter includes that example. The data template selector is a class named CustomerDataTemplateSelector. Here is the code for that class (code file: CustomerDataTemplateSelector.vb):

Public Class CustomerDataTemplateSelector      Inherits Controls.DataTemplateSelector        Public Property ActiveCustomerTemplate As DataTemplate      Public Property InactiveCustomerTemplate As DataTemplate        Protected Overrides Function SelectTemplateCore(item As Object,                                                      container As                                                       DependencyObject)                                                      As DataTemplate            Dim c As Customer          c = CType(item, Customer)          If c.Active Then              Return ActiveCustomerTemplate          Else              Return InactiveCustomerTemplate          End If        End Function    End Class  

As you can see, in the example, the data template used is determined by the Active property of the customer record.

Then a new data template was added to the resources collection, using the key InactiveCustomerTemplate. The XAML is similar to the data template used earlier in the ListView example, except that the Image control is removed and text elements get a gray foreground (code file: InactiveCustomerTemplate.xaml):

<DataTemplate x:Key="InactiveCustomerTemplate">      <Grid HorizontalAlignment="Left" Width="250" Height="250"            Background="{StaticResource   ListViewItemPlaceholderBackgroundThemeBrush}">            <StackPanel Margin="4" VerticalAlignment="Top"                  Background="{StaticResource   ListViewItemOverlayBackgroundThemeBrush}">              <TextBlock LineHeight="28" FontSize="24"                          Text="{Binding CustomerName}"                          Foreground="Gray"                          Style="{StaticResource TitleTextStyle}"                          Margin="15,0,15,0"/>              <TextBlock LineHeight="24" FontSize="18"                          Text="{Binding Phone}"                          Foreground="Gray"                          Style="{StaticResource TitleTextStyle}"                          Margin="15,0,15,0"/>              <TextBlock LineHeight="28" FontSize="24"                          Text="Inactive" FontStyle="Italic"                          Foreground="Gray"                          Style="{StaticResource TitleTextStyle}"                         Margin="15,20,15,20"/>          </StackPanel>      </Grid>  </DataTemplate>  

Then an instance of the CustomerDataTemplateSelector was added to the resource collection, with a key of MyCustomerTemplateSelector:

<local:CustomerDataTemplateSelector x:Key="MyCustomerTemplateSelector"              ActiveCustomerTemplate="{StaticResource Standard250x250ItemTemplate}"              InactiveCustomerTemplate="{StaticResource InactiveCustomerTemplate}" />  

Notice how the templates to be used are assigned to the ActiveCustomerTemplate and InactiveCustomerTemplate properties, based on the resources that are already in the XAML.

The final step is to change the GridView XAML to remove the ItemTemplate property setting, and set the ItemTemplateSelector property to the MyCustomerTemplateSelector resource:

<GridView Grid.Row="1" Margin="120,0,0,0"             ItemTemplateSelector="{StaticResource MyCustomerTemplateSelector}"            ItemsSource="{StaticResource CustomerList}" />  

The resulting program will yield a screen much like .

The earlier GridView example has been modified to use a data template selector. Inactive customers are rendered in a different template from active customers.

13.10

Pickers

In earlier versions of XAML, as well as other UI technologies such as Windows Forms, getting access to the file system was done via a set of common dialogues. The classes were actually thin wrappers over parts of the Windows API, with the wrappers serving to make the dialogues object-oriented.

In Windows 8, the native API is object-oriented. Therefore no wrappers are needed. Accessing the file system dialogues means calling the corresponding API objects. Instead of being called common dialogues, they are called pickers.

Since these are native API objects, they don't reside in any of the XAML related namespaces. Pickers and their associated helper classes are in the Windows.Storage.Pickers namespace.

The calling conventions are also different. Windows 8 apps are required to do just about everything asynchronously, which lets apps be suspended, hibernated, switched out, etc., more easily. So whereas common dialogues are modal, pickers are required to be asynchronous.

Chapter 5 discussed asynchronous syntax for Visual Basic, and you'll need that syntax to work with pickers. Here is an example routine that could be place behind a button to access the FolderPicker, which is the object used to choose a folder object and returns an object of type StorageFolder (code file: FolderPickerExample.vb):

Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs)      Dim fp As New Windows.Storage.Pickers.FolderPicker      fp.SuggestedStartLocation =             Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary      fp.FileTypeFilter.Add(".docx")        Dim PickedFolder As Windows.Storage.StorageFolder      PickedFolder = Await fp.PickSingleFolderAsync      If PickedFolder Is Nothing Then          ' User did not choose a folder      Else          ' PickedFolder contains the folder chosen by the user          Dim md As New MessageDialog("The user chose " & PickedFolder.DisplayName)          Await md.ShowAsync()        End If    End Sub  

Notice that the click event handler is declared with the Async keyword, and that the Await keyword is used before the FolderPicker method call, which is PickSingleFolderAsync. The MessageDialog showing the result is also used asynchronously.

ProgressRing

Previous XAML platforms has a ProgressBar control to indicate progress on an operation. Windows 8 has such an element, but it also has a complementary ProgressRing control.

When you use ProgressBar, you are responsible for giving it periodic updates as to the completion percentage. With ProgressRing, that's not necessary. It just continually displays an animation indicating that an operation is ongoing. No progress value is involved.

All you do to make a ProgressRing active is to set the IsActive property to True. The ProgressRing will show and animate until IsActive is changed to False. It's common to do this in code, but for simplicity, the example below will bind IsActive to another control, which is a ToggleSwitch.

Since the example for ProgressRing uses ToggleSwitch, let's cover that first and then look at the XAML example for both of them.

ToggleSwitch

In earlier XAML platforms, CheckBox was the usual way to indicate a true/false selection. In Windows 8 XAML, CheckBox is still present, but should be used much more sparingly. If the user needs to turn settings on or off, or turn on actions, the ToggleSwitch is preferred because it is designed to fit well into the Windows 8 UI standards.

CheckBox uses the IsChecked property to expose a true/false or on/off status. The corresponding property for ToggleSwitch is named IsOn, which also exposes a Boolean.

CheckBox is a ContentControl, and simply displays a single piece of static content. ToggleSwitch is not a ContentControl. Instead, it has three properties that allow content:

1. OnContent—the content shown when IsOn is True.
2. OffContent—the content shown when IsOn is False.
3. Header—content to tell the user what the ToggleSwitch is for. This content displays above the ToggleSwitch by default.

Let's look at an example in which a ToggleSwitch is used to turn a ProgressRing on and off:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">      <StackPanel Orientation="Horizontal">          <ToggleSwitch   Name="ProgressToggleSwitch" FontSize="28"                           Header="ToggleSwitch and ProgressRing Example"                           OffContent="Idle" OnContent="Working" />          <ProgressRing Height="60" Width="60"                         Foreground="Aquamarine"                         IsActive="{Binding ElementName=ProgressToggleSwitch,   Path=IsOn}"/>      </StackPanel>    </Grid>  

This XAML can be placed in a new Blank App, and when the ToggleSwitch is turned out, the screen will look like .

The ToggleSwitch on the left controls the ProgressRing, which animates the dots in a circle.

13.11

Other New Elements

There are several other new controls and elements, but in this brief introduction to Windows 8 XAML, you can't cover them all. Most of them are straightforward, and should be easy to learn when you need them. Here are some of the more notable new controls and elements that you will be omitting:

Old Elements with New Usage

In general, Windows 8 XAML does a pretty good job of keeping down confusion between XAML platforms. You've seen that it has a number of its own elements that are optimized to Windows 8 purposes, such as RichEditBox. Since it has a different name from the RichTextBox control in earlier XAML platforms, it's much less likely for you to get their functionality mixed up.

However, there are two elements that have exactly the same name in Windows 8, but have some critical differences you should know about. They are Frame and Popup.

Frame

The Frame control existed in WPF and Silverlight versions of XAML, but it had different capabilities in each. The Silverlight version of Frame, for example, had integration with the browser's address bar.

The Frame in Windows 8 has its own differences. For that reason, Chapter 12 didn't discuss the Frame. Here are the basics of the Frame in Windows 8 XAML.

The Frame is used most often as a host for a Page, or more rarely, a UserControl element. Frame has a Navigate method to place a Page in the Frame. Note that this is different from the NavigateURI used in Silverlight's Frame. Instead of using a URI for navigation, in Windows 8 XAML, most navigation is done by navigating to a new instance of a type.

You can place a Frame in a XAML surface, and use it as a host for part of your view. Frame is also commonly used as the root ContentControl for an entire application, with the Navigate method of the Frame used to transfer application control to entirely different views.

Frame's Navigate method has two overloads. If your Frame is named MyFrame, and you want to navigate it to a new view of type CustomerPage, then the two overloads look like this:

MyFrame.Navigate(CustomerPage)    MyFrame.Navigate(CustomerPage, ParameterObject)  

In the second overload, ParameterObject can be an object of any type. Normally, you would construct such an object that held the information which needed to be transferred to the new instance of the CustomerPage.

The reason Page is most often used as the navigation target is that Page has an OnNavigatedTo method that is fired when the Page is activated by navigation. The parameter object in the second overload above is available in the arguments for that method. The most common pattern, then, is to look at the parameter object, and take whatever steps are appropriate to configure the target Page. For example, the parameter object might include a database ID, and the ID could be used to set the DataContext for the Page.

You will examples of Frame usage, including the Navigate method, in the section below on the standard application templates used by Visual Studio to produce a new application.

PopUp

The PopUp element is familiar to most XAML developers. It provides a surface that is guaranteed to float on top of a view. Some internal controls, such as ComboBox, use PopUp internally. In the case of ComboBox, the items that appear when the ComboBox is opened are on a PopUp element.

In Windows 8, the PopUp is used for similar purposes as earlier versions of XAML, but it has some missing capabilities compared to earlier versions. In particular, whereas the WPF and Silverlight PopUp elements know how to position themselves relative to another element on a page, the Windows 8 PopUp does not. It has HorizontalOffset and VerticalOffset properties to position the PopUp on the entire visual surface, but it is your responsibility to calculate those offsets and configure the PopUp before showing it.

As with older versions of PopUp, the interior of the PopUp is determined by setting the Child property of the PopUp. It's common for the Child to be set to a Grid, UserControl, or other container, and that becomes the design surface for the visuals that will display in the PopUp.

After a PopUp is configured, it is brought into view by setting the IsOpen property to True. Then, when it's finished, IsOpen should be set to False. Usually various touch and mouse events are detected to indicate that the user is no longer interested in the PopUp, and then the PopUp is closed in the code for those events.

. then shows the menu that results from pressing the glyph, with a submenu of system resources.

The glyph that calls up advanced settings for a property has been moved to the far right in Visual Studio 2012.

13.12

The advanced settings menu has several options for working with resources. The Local Resource and System Resource options now have a scrollable list of resources.

13.13

It's also easier to choose resources to associate with a property of type Brush. The Brush editor, which automatically appears in the Properties windows for properties that take a Brush such as Background, Foreground, and Fill, now has easier access to available Brush resources. At the top of the Brush editor, where the brush type is selected, a new option appears at the far right to get a tab showing all the available Brush resources.

Common vs. Advanced Property Categories

Each category of properties is now divided into Common and Advanced properties. Common properties are those the Visual Studio team decided that you are likely to set frequently. Advanced properties are expected to be set less frequently, and are available by pressing the down arrow at the bottom of the category.

As in Expression Blend, if you search for a property by name, it appears in the Properties window regardless of whether it is in the Common or Advanced group for its category. Unlike past versions of Expression Blend, the Properties window in Visual Studio 2012 retains the ability to sort properties alphabetically.

Transform Properties

You can now set Transform properties in the Visual Studio 2012 Properties window. The two properties in the Transform category are RenderTransform and Projection. Even though Chapter 12 did not include coverage of transforms and projections, most experienced XAML developers will be familiar with them.

Visual Studio 2010 had no ability to set RenderTransform or Projection property values in the Properties window, and developers were forced to either use Expression Blend or fall back on hand-coded XAML. Now the Expression Blend property editor for those properties is available in Visual Studio. shows a RenderTransform being set with a rotation angle of 15 degrees.

The Properties window now includes the ability to set Transform properties such as RenderTransform. Here, a rotation angle of 15 degrees is being set.

13.14

Animation

One of the more difficult aspects of developing in earlier XAML platforms was working with animation. While those platforms had very rich animation support, using it required a high level of expertise.

Windows 8 shares the rich animation support supported by earlier versions, but it adds an entry point that makes commonly used animations very accessible. A set of animations called ThemeTransitions are available merely by adding them to the Transitions property for an element, or the ChildTransitions property for a panel.

To use a ThemeTransition, in the Properties window, locate the Transitions property and click the button with the ellipsis on the right. You will see a dialogue similar to .

Setting transitions in the Visual Studio 2012 Properties window. The drop-down of available transitions is shown open.

13.15

To add a transition animation, first select the kind of transition you want to work with by picking an option in the drop-down on the bottom right. This drop-down has been opened in . For example, suppose you choose EntranceThemeTransition. You can then add animation for that transition by pressing the Add button.

At that point the dialogue will look like . Notice that the transition has several properties you can use to tweak the animation. In this case, you can specify the amount of horizontal and vertical animation applied to the animation when it appears.

The transitions editor with an EntranceThemeTransition added

13.16

If you add such a transition to an element, when the element is added to the UI, or when the element changes in visibility from Collapsed to Visible, the transition will be animated. The code download for the chapter includes a sample program that animates a rectangle when it appears.

. The items can be scrolled vertically with swipes or a mouse.

The starting screen for a Split App

13.17

The screen for a group of items in an application created with the Split App template. Selecting an item in the ListView on the left brings up the item on the left.

13.17

Grid App

The Grid App template has more complex navigation built in than the Split App template. If you create an application with the Grid App template, the starting screen for your application will look like .

The starting screen for a Grid App

13.19

From this point, the user can touch or click on one of the group names (such as “Group Title 1”), or select one of the items in a group. If the user selects a group name, the resulting screen looks like . Selecting an item brings up the screen in .

The Group screen in an application created with the Grid App template

13.20

The screen for an individual item in an application created with the Grid App template

13.21

Layout Aware Pages

All the pages placed in a new application by the Grid App and Split App templates are layout aware. That means they know how to respond when the app is transitioned to a snapped view, or between portrait orientation and landscape orientation.

It's still your responsibility to determine what the page does for those orientations. Only very simple default behavior is included in a layout aware page.

You can also use layout aware pages in an app created with the Blank App template. There are six item types in the Add Item dialog that are layout aware pages. shows the Add Item dialogue with a bracket around these six page types.

The Add New Item dialog in Visual Studio 2012, with a bracket showing the item types that are layout aware pages.

13.22

If you add one of these page types to a Blank App, in addition to getting a new item for the layout aware page, several new items are also added to the Common folder.

Items in the Common Folder

The Common folder is created by all Windows 8 XAML application templates, but in a Blank App, it only holds StandardStyles.xaml. In Split App and Grid App, it holds several additional items. As just mentioned, these additional items are added to Common folder for a blank app if a layout aware page is added to the project. Let's take a look at the contents of the Common folder for a project containing a layout aware page.

There are two base classes in the Common folder, BindableBase and LayoutAwarePage. BindableBase is used as the base class for the sample data models, and it implements INotifyPropertyChanged to provide property change notification. You can use it as a base class for your own data models if you like.

LayoutAwarePage is used as the base class for all the layout aware pages, and it includes functionality to help with navigation and to help application pages work better with Windows 8. For example, LayoutAwarePage has events for switching to a snapped view, or switching between portrait and landscape orientations. When you add new Page items to your project, it's a good idea to base most of them on LayoutAwarePage instead of the standard Page element.

The Common folder also contains several useful helper classes. One is a helper object for app suspension, called SuspensionManager.vb. Two commonly used value converters are present, BooleanToVisibilityConverter and BooleanNegationConverter. These converters provide functionality needed in the majority of XAML apps; in fact, WPF included BooleanToVisibilityConverter is its framework libraries. These converters are not part of the framework libraries. They are just source code in the application templates. Still, at least you don't have to write them.

StandardStyles.xaml

As mentioned earlier, the Common folder includes a set of resources in StandardStyles.xaml. You'll probably use those resources a lot, and in fact some were used in earlier examples in this chapter. Most of the resources are Style definitions, hence the name of the item.

StandardStyles.xaml is loaded into the application in the App.xaml Resources collection. That means that all styles in StandardStyles.xaml are available throughout your application.

StandardStyles.xaml has almost 2,000 lines of resources. However, as discussed in the section above on app bars, StandardStyles.xaml contains dozens of styles for app bar buttons, all commented out. You should be aware of the styles for app bar buttons in StandardStyles.xaml, and uncomment the ones you need.

Except for uncommenting app bar button styles, it's a good idea to avoid major changes in StandardStyles.xaml until you become very familiar with the application templates and how these styles are used. If you decide you want your own version of one of these styles in a page, you can copy the Style from StandardStyles.xaml into the Resources collection for that page, and make the changes there. As discussed in Chapter 12, local resources with the same name override resources at a higher level in the application.

Online Documentation for Grid App and Split App Templates

The Grid App and Split App templates include a link to online documentation for the template. It is located at the top of the code-behind module for App.xaml. Other pages in the template also have links at the top, which goes straight to the documentation for that particular page.

The documentation is reasonably extensive, and is likely to be refined over time, so it is not reproduced here. If you want to use these templates, you'll need to study that documentation in depth.

shows the Declarations page, with the list of available declarations dropped down.

The Package.appmanifest Declarations page, showing the drop-down of declarations. The Search contract declaration is selected in the drop-down.

13.23

To declare support for a Search contract, just select Search in the list and then press the Add button. Some properties will come up on the right side in case you want your app to delegate the searching to another app. To do searching within your app, you can ignore those properties.

Then you need to handle the associated event for searching at the application level. In the code behind for App.xaml, place the following sub (code file: SearchContract.vb):

Protected Overrides Sub OnSearchActivated(args As SearchActivatedEventArgs)        ' Carry out search operations here      ' and display results somewhere in the app.      ' You might use LINQ or other techniques to find records      ' that match args.QueryText.        ' In this demo version, I'm just passing the search      ' query string to the main page of the app.        Dim pg As MainPage      pg = CType(CType(Window.Current.Content, Frame).Content, MainPage)        ' Search query text is available in args.QueryText      pg.DisplaySearchResults(args.QueryText)    End Sub  

Finally, place a TextBlock somewhere in MainPage.xaml with the Name set to SearchResultsTextBox. Then place the DisplaySearchResults method referenced above in the code-behind for MainPage.xaml:

Public Sub DisplaySearchResults(sQueryString As String)      SearchResultsTextBox.Text = "Search activated with query string " &   sQueryString  End Sub  

This is enough to show that the search operation is active in the app. Run the app, swipe the charms bar into place, and select the Search charm. Put in a search query string, and press the search button. You should see the TextBlock update with the search query string you entered.

How you actually carry out the search operation in your application is up to you. Typically, you would either carry out a database query, or use LINQ to query against data you have already fetched.

Updating views directly from the App.xaml code behind is not a good practice in general. This example is just to show you the basics. If you intend to handle searching, a good pattern for your code is to have a property on your data model or viewmodel that holds search results. Then you can bind an appropriate element to that property. That way, the App.xaml does not need to know where the search results are displayed. It needs only to update the model.

Summary

This chapter has provided a brief introduction to some of the most important concepts in creating Windows 8 XAML apps. It's only intended to get you started. If you find yourself working on complex Windows 8 apps, you may wish to find a more comprehensive resource.In the next chapter, the focus shifts from XAML-based user interfaces to HTML interfaces created with ASP.NET.

Назад: Chapter 12: XAML Essentials
Дальше: Chapter 14: Applications with ASP.NET, MVC, JavaScript and HTML