How to Write a WinRT XAML Metro App
Easily build an app based on the Windows 8 WinRT Developer Preview, using your existing XAML and C# skills
January 30, 2012
For anyone paying attention to the Microsoft space since September 2011, Windows Runtime (WinRT) has been a hot topic among the developer crowd as theplatform for developing the next generation of Windows 8 immersive applications. The most exciting thing about WinRT is that both today's webdevelopers and XAML developers have a place in this new environment: WinRT runs just as well when using HTML5 and JavaScript as it does when using XAMLand C#. This means that, a few API changes aside, skill reuse is at a maximum. Anyone who is currently working with Silverlight or Windows PresentationFoundation (WPF) should have no problem transitioning into WinRT.
With that in mind, let's take a closer look at WinRT. In this article, we will first explore one of the pre-defined templates in WinRT to see how itcompares with the XAML we know today. Then we will start a new application from scratch using our existing XAML and C# skills.
Diving In
The first step in creating any application for WinRT is to open Visual Studio. With the Windows 8 Developer Preview, we also received access to theVisual Studio 11 Express Developer Preview, giving us everything we need to develop, run, and debug a WinRT application even in this early stage ofWinRT's life. Opening Visual Studio 11, we are presented with a familiar start screen, so we can click New Project to see what templates are installedwith Visual Studio 11. Figure 1 shows the New Project screen.
Figure 1: New Project screen in Visual Studio 11
We can see options for JavaScript, Visual Basic, Visual C#, and Visual C++; we'll choose Visual C#. Doing so presents us with five options to choosefrom for a new project:
Application: an empty application, a blank slate to work from
Grid Application: an application with predefined views for viewing hierarchical data. In this case, the default setup works well for an RSSreader-style app because it has logic for navigating through items of multiple collections as well as placeholders for visual elements.
Split Application: a typical list-and-details style application that allows for browsing through a condensed view of items in one list while adetails view offers more specific information
Class Library: same as in .NET, a class library that can be used within a WinRT application
Unit Test Library: also the same as in .NET, this provides a library for adding unit testing to your application.
Now we will explore what an in-process WinRT Metro application looks like. We'll first select the Split Application type and click OK. Before writing aline of code, click Run, and you'll see an application that looks a lot like the one in Figure 2.
Figure 2: Split Application example
You can choose different items from the left-hand list to see the full details on the right, or alternatively, click the back-arrow button to see themain hub of the application and the different collections that are available.
Split Application XAML Looks Like Silverlight XAML…
The project will begin with CollectionPage.xaml open, so let's look at that page to see some of what is taking place in this application. For yourreference, CollectionPage is the page you would have seen if you clicked the Back button on the start-up page for the application, as it normallystarts on SplitPage.xaml.
The first line we see is a UserControl, shown in Figure 3 -- a familiar item for both Silverlight and WPF developers. This worksessentially the same as in both of those platforms, providing a component that allows for easy reuse throughout your application. In this case, all theUserControls within the application are being used full-screen, but you still have the option to load other controls onto your page. Stepping down afew lines, we can also see that the UserControl has a Resources collection containing a CollectionViewSource with both an x:Name and x:Key -- meaningthat we can still set names to reference from code as well as keys to be used for referring to resources.
Stepping down a bit further, we get to our page content, with the main layout panel being a Grid. This has the same properties you would expect fromWPF and Silverlight, including Row and Column definitions as well as a VisualStateManager (VSM). In WinRT immersive applications, the VSM becomes veryimportant because it allows for state transitions between Full (landscape), Portrait, and Snapped views. For anyone unfamiliar with these views, thebreakdown is as follows:
Full: a landscape view of the application taking up the entire screen (the typical Metro/immersive application)
Portrait: as the name suggests, a view that has been turned on its side. Using the tablet form factor as an example, Windows 8 tablets willgenerally always default to a landscape setup; however, in some scenarios a Portrait view may benefit your application.
Snapped: Windows 8 allows for a "snapped" view in which one application takes up a portion of the screen while a main application is still inuse. Not providing a view for the Snapped view state could make your application unusable if users want to have two applications running side by side.
Getting into the Grid contents, we see two main controls handling the bulk of this view: GridView and ListView, as shown in Figure 4.These controls are new to WinRT; however, GridView functions much like a wrap panel handling items in a stacked order based on item size, whileListView is very close to the Listbox in Silverlight and WPF. The major difference with both of these controls is that though they bear some similarityto their current counterparts in .NET, with WinRT you automatically get extra functionality specific to the touch-based interface as well as controltemplates with built-in support for things like selection. The code for these two controls should look very familiar to any current XAML developer,with Binding providing the data to display and StaticResources being used to handle templates, brushes, and styles.
Creating an App from Scratch in WinRT
Instead of working from a pre-existing template, we will start from scratch with the basic Application template and see just what it takes to get upand running with WinRT in XAML.
Start by creating a new project and ensure that you have the Visual C# Metro templates selected. Choose the basic Application template, give yourproject a name (we are using HelloWinRT for this example), and click OK for Visual Studio to start up your new project. For a Silverlight or WPFdeveloper, the initial MainPage.xaml view that you see should look very familiar, as shown in Figure 5.
Running this now would provide just a blank screen, so we will start adding some controls to our page to bring things to life. While Visual Studio 11provides us with a new designer that is a hybrid of the old Visual Studio 2010 editor and the Microsoft Expression Blend editor, we'll be refreshingour XAML skills to demonstrate just how much of what we already know carries over to the WinRT platform.
Start by adding some Row and Column definitions to the LayoutRoot grid. In this case, we will create two rows and two columns, each having the firstinstance sized at 120 pixels while the other will take the rest of the available space:
We can now proceed to give our application a title like we saw in the Split Application template. Although normally you would want to place your stylesin either the App.xaml for reach throughout the application or into a Resource Dictionary for easy modification and portability, for the sake of thisarticle we will keep all our styling and templates inline. In this case, we can add a TextBlock for the title with the following settings:
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="10,0"
FontSize="64" />
These settings result in changes occurring on the design surface, as shown in Figure 6.
Figure 6: "Hello WinRT" title
Next we will use one of the new controls we saw in the previous section, the GridView, to display some data. Without knowing all the functionality ofthis control, we can go ahead and add an instance to our XAML and then step into code to provide it with some sample data. Since we have some rows andcolumns defined, we will set both a Grid.Row and Grid.Column on our control:
We'll make some modifications later to how our data is displayed, but at this point we will spend a little time with code to provide data to display inour example.
C# in WinRT
We will be approaching C# in this article in the same way we approach the XAML aspect of WinRT: Assuming some pre-existing knowledge of .NET, we wantto set about a task that we know how to accomplish in .NET with Silverlight or WPF and see how that translates to WinRT. With that in mind, right-clickthe project name and choose to add a new class named ExampleDataItem. This class will contain a few items that we can use to showcase the GridViewcontrol in action. For this purpose, we will make this a relatively simple class that utilizes a few different types:
class ExampleDataItem {
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime ItemDate { get; set; }
public ExampleDataItem() { } }
This class is fairly easy to code and looks just like it would if we were to write this in standard .NET. Now that we have a class to use, let's stepinto the code-behind for MainPage.xaml.
Knowing that MainPage is a UserControl, there should be a Loaded event that fires when the control has finished loading (i.e., any controls we havedefined are loaded and can now be accessed via code). So within the main constructor, after the call to InitializeComponent, we'll type this.Loaded andpress Tab twice to generate a Loaded event. In this event we will create a new List of ExampleDataItems and generate some quick data for it using a forloop and two predefined description strings for the Description field. After that, we will check and see that our GridView definitely has anItemsSource, so we'll then set the ItemsSource to our list. The complete code listing should now look like that in Figure 7.
We can now run our application and see how everything looks. The results, shown in Figure 8, are exciting, but I think we can make this look a littlemore appealing than just displaying the class type.
Figure 8: Results of running the example application
One nice thing that you may have noticed is that as our HelloWinRT.ExampleDataItems were loading, there was both an animation effect and a staggeredloading effect. We get these animations for free with WinRT and the GridView; however, we can also customize them or remove them entirely.
XAML Templating
At this point, we have created a new application using the WinRT GridView as well as some dummy data coming from the code-behind. But even with theanimation and loading effects that we get for free with WinRT, the application is not quite looking that good yet. The next thing we will look into ishow we can provide a few styles and templates to turn our HelloWinRT.ExampleDataItem display into something a little more meaningful.
Back into MainPage.xaml, we want to work within the GridView to control how our items are being displayed. If you recall the previous image displayingour classes, the effect achieved out of the box with the GridView control looks suspiciously similar to the effect of a WrapPanel control. We want ouritems to have a little more space, though, so our first step is to replace the ItemPanel of our GridView with another type of panel. Since we may havea lot of data loading and want optimum performance, we'll stick with a VirtualizingStackPanel because it will provide the horizontal layout that we'relooking for and will list items sequentially instead of stacked to the available space. This is accomplished using the following five lines of code:
Note that we do not have to specify anything about how the items will display; rather we are simply replacing the original ItemsPanel with a newtemplate that contains a VirtualizingStackPanel. Thanks to the way XAML controls are built, we can easily swap out different templates and change thelook and feel of controls by replacing or modifying specific templates without needing to have the code for the entire control available. Figure 9shows the results of this code.
Figure 9: Initial layout after adding code with a new template containing a VirtualizingStackPanel
Next we want to modify how our individual items display. Similarly to Silverlight or WPF, the WinRT variant of XAML allows us to replace theItemTemplate of a control to override the default item display. If we wanted a more normal ListBox display with a single line per item, we could alwaysset the DisplayMemberPath on the control to one of our object properties, but since we have the fake data generated we should display it.
Going back into the GridView XAML, we'll now be adding a new DataTemplate containing a Grid inside of GridView.ItemTemplate:
With our new Grid, we can easily add some formatting that will allow for displaying items through the binding system. Since WinRT contains the sameconcept as the other XAML languages for both DataContext and ItemsSource, we can easily use Binding statements to get data to display within ourDataTemplates by binding to the property name. For example, after adding a few row definitions to our new grid, we can add the following few lines todisplay the Name property of each object:
FontSize="24"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="5" />
If we run the code now, we can see the name displayed quite prominently, still featuring the built-in animations as well as selection visuals, as shownin Figure 10.
Figure 10: Modified layout with formatted grid
Since we can see that setting the Binding statement to Name worked flawlessly, we can see that the same binding system we are used to also works in theWinRT XAML platform. This means that for any other data we want to display, we should be able to use similar syntax to display some of our otherproperties. By adding a few more TextBlocks to our template, the resulting code will display our full item:
Figure 11 shows the final result.
Figure 11: Fully modified application layout
There's one thing to note about this developer preview version of WinRT. In Silverlight or WPF today, we could use StringFormat within our Bindingstatement to make the date look a bit nicer, but this functionality is currently missing in WinRT. If we wanted a certain type of date display, wecould either modify the class or add a converter to display the preferred format.
Application Navigation
You might wonder how we go from this page to, say, a details page for the application. After all, if we were building an RSS reader app, we would needa lot more space to read the article than is available in our current view.
Stepping right into the code, we want to add an event handler for the SelectionChanged event in our GridView. When this fires off, we will want tonavigate to a new UserControl displaying the full information for our object. In order to do this, we will need to add a new UserControl namedDetailViewControl.xaml. Since we already have a template designed to display our item within MainPage.xaml, we can copy this template and paste it intothe new UserControl to provide a data display. The only thing we want to add is a new Button with a click event set. The resulting DetailViewControlXAML will look like the code in Figure 12.
We'll go ahead and work with the C# behind this page, then return to MainPage to ensure we can navigate here.
On the constructor of DetailViewControl, we want to add a new parameter, specifically an ExampleDataItem. Since we know that the binding system worksperfectly well, we can then set the DataContext of this control to the passed-in ExampleDataItem, and our data will display without a hitch:
public DetailViewControl(ExampleDataItem exampleItem)
{
InitializeComponent();
this.DataContext = exampleItem;
}
The last thing we need to add is some code for when the Back button is clicked. With the current WinRT model, everything is handled via the applicationWindow, so navigating back is actually accomplished by setting the content for that instance. Since we know we are going back to MainPage, the code inthe Button click event will look something like this:
private void xGoBackButton_Click(object sender, RoutedEventArgs e)
{
Window.Current.Content = new MainPage();
}
Now that we can get back from this page, we need a way to navigate to the page. This is accomplished with very similar code from our MainPage.xaml.csin the SelectionChanged event handler. Once we perform a null check to ensure we have an item, navigating to the new control is as simple as settingthe Window.Current.Content, as we did in the new control to go back:
private void xGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ExampleDataItem exampleItem = e.AddedItems[0] as ExampleDataItem;
if (exampleItem == null)
return;
Window.Current.Content = new DetailViewControl(exampleItem);
}
The end result is an application that begins on MainPage.xaml and allows navigation to get a better view of each data item, complete with a Back buttonto allow users to return to the MainPage. Figure 13 shows a final view of the DetailViewControl once our application is running with navigation.
Figure 13: Application with DetailViewControl in action
Wrapping Up
I hope that this article has accomplished the goal of showing you just how easy it is to work with the new WinRT XAML platform. For anyone who isalready familiar with .NET, and especially so for anyone working with Silverlight and WPF today, using WinRT feels very familiar, and many conceptsthat you use in application development today will carry over to the Windows 8 platform. Just keep in mind that this article was written based on theDeveloper Preview version of WinRT; when the Beta version is released, some of the concepts discussed herein may change or require an update.
If you want to take this sample application a bit further, try extracting templates into the App.Xaml file for easier reuse or moving navigation logicto a static handler within App.Xaml.cs. You can do so using the examples in the Grid and Split templates that come pre-loaded with WinRT XAML.Otherwise, keep exploring! WinRT is brand-new, and the Beta should be just around the corner, so you will have ample opportunity to discover just whatthis new framework can do for building immersive Windows 8 applications.
Evan Hutnick is a Solutions Consultant at Telerik, enabling customers to deliver more robust and complete solutions built with the XAML platforms. Evan is also aSilverlight Insider, and last but certainly not least, he is a proud father, husband, and independent game developer.
About the Author
You May Also Like