Getting Started with XAML

See for yourself the flexibility of XAML, as Jesse Liberty and Alex Horovitz show you how to create an interactive Windows application declaratively, in .NET 3.0.

Creating .NET 3 Applications with XAML

Microsoft’s .NET 3 introduces the option of using markup to create Windows applications, much as we’ve used HTML and related markup to create web applications for the past decade. This is a major break-through and a distinct step on the path towards merging the development process of creating web and desktop applications.

This new markup language is called eXtensible Application Markup Language, or XAML (pronounced /’zæmÉl/ to rhyme with camel). Every XAML object represents a CLR object, and every CLR object may be created declaratively in XAML.

In this article we’ll create a meaningful, working XAML application. We’ll take you through the creation process, with the goal of demonstrating the flexibility of the language and acquainting you with the fundamentals of creating a working Windows application declaratively.

Getting Started With XAML

Every Window is declared as a panel and every property is declared as an element, or an attribute of an element. In its simplest form, this looks very similar to HTML:

In fact, XAML is an XML-based superset of HTML, combining the power of HTML to define content, with that of CSS to define layout (carefully separating the two, to the relief of experienced CSS programmers).

Note: To follow along with the examples in this article, you will need to install the release version of .NET 3, which will run happily and harmlessly side-by-side with .NET 2 on any computer running Vista, Windows XP (SP2), or Windows Server 2003 SP1.

Core XAML Elements

While we won’t even try to cover everything in XAML in this article, we will cover some core elements, both to give you a feel for how XAML applications work and to lay the ground work for walking you through a robust sample application.

A panel element is a container. Panels come in several different shapes and sizes. Depending on their features they are useful for containing other elements.

Root elements are special derivations of panel elements and serve as the fundamental container for the page. Each page will have exactly one root element.

Control elements are user-manipulated objects that help with data or user interactions.

The PelotonShack Project

With these elements, we are going to build a data-bound page that will offer a catalog of bicycle parts from the AdventureWorks2000 database. On the left, there will be a scrolling display of images taken from the database. As the user scrolls over each image, it (that is, the image, not the user) will grow slightly and come into focus. If the user clicks on the image, it will be highlighted in the larger area on the right and its details will be displayed in text, as shown in Figure 1.

 363-Fig1_XAML.gif
Figure 1: in which the selected image (not the user) is shown in detail in the right hand panel

Creating the Web Application

To create this application, begin by opening Visual Studio and creating a new Project. Choose the Windows Application (WPF) template, set your directory and set the solution name to PelotonShack, as shown in Figure 2.

363-Fig2_XAML.gif
Figure 2: creating the web application

Windows will create a development environment and establish your first window, which it will also name for you:

While there will certainly come a time (and soon) when Visual Studio will offer a complete and working toolkit for building WPF applications, for now we’re going to have the most success and least frustration if we write directly in XAML, in the lower markup window.

Start by setting the height of Window1 to 600 and the width to 900 (you can fine-tune these numbers later).

Within the Grid, we’ll want to add Grid.Resources (to manage styles, GradientBrushes, etc.) and we’ll want to add column definitions.

The Header

An easy place to start is by adding the header, as shown in Figure 3:

363-Fig3_XAML.gif

Figure 3: adding the header

To create this, we’ll use a text block and style it. The text block is pretty straightforward:

Notice, however, that the TextBlock element is marked with a style reference to the DynamicResourceTitleText‘. Resources are separated out in their own section, so the complete XAML at this point looks as shown in example 1:

From such humble beginnings, all the rest will follow in just a few easy steps.

 Adding the List Box

To add the list box of products, we need to accomplish a few tasks all at the same time.

1. Add a panel to hold the list box in a specific place in our window.

2. Add a list box to hold the images.

3. Include style information to tell the list box how to render the data (as images).

4. Bind the list box to a query of the images from the database.

The panel we’ll use to hold the list box will, ultimately, have the list box on the left, the larger image on the right and text below. That is, it needs to have two columns and a row. A stack panel can hold items one above the other or one next to another, but when you need to have both rows and columns, the panel you need is a grid:

The first two lines set up the grid’s attributes (margin, width, etc.). This is followed by the Grid column definitions, in which we define two columns: one will occupy 1/3 of the grid’s width, while the second will occupy the remaining 2/3 of the grid’s width. One row is defined in the Row definitions.

Following the Row and Column definitions are two content controls: MasterPane and DetailsPane. The second content control, DetailsPane, is left empty for now. The first content control holds the list box. The key attribute for the list box is that the ItemSource is set to bind using the default mode. Since this is placed within a window where the DataContext was set to ‘theTable‘, the list box will use ‘theTable‘ as its binding context. The style for binding is set by the ItemTemplate.

It consists of a stack panel whose horizontal alignment is set to center the items and whose image will be retrieved from the binding where the path is set to ThumbNailPhotoFilePath . This is a column that will be retrieved for every row as a result of the select statement that will generate the DataTable we’ll be using as the DataContext for this list box.

All of the work for generating the DataTable, and associating it with the context, is accomplished in the code-behind file, the constructor for the Window class:

The net result is a scrollable list of images extracted from the database, as demonstrated in Figure 4:

363-Fig4_XAML.gif

Figure 4: a scrollable list of images

Adding Events

We’d like to be able to mouse over the list and make the image currently highlighted by the mouse stand out more than the others. We’ll do this by reducing the opacity of the images to 60% and then increasing that to 100% when the mouse hovers over the image. To accomplish this effect, we add animation, using a story board.

We’ll indicate that the starting opacity is .60 (60%); and we’ll designate that over the course of two tenths of a second that opacity should increase to 100% when the event MouseEnter is registered. This opacity will also return to 60% when the MouseLeave event is raised. We declare these requirements by creating a ProductTemplateItemStyle for the ItemContainer and then creating that style within the Resources section:

The effect is powerful: As you mouse over each item, it appears to light up.

Creating the Detail View

We can now add the second container control to hold the larger image of the selected item and its description. The most interesting thing we’ll do here is add a ‘reflection’:

Creating the Reflection

The reflection is created by adding a grid within the content control. Within that grid we will add a stack panel. The image is stacked on top of a rectangle that uses a LayoutTransform to flip the image upside down (ScaleY = -1). The rectangle then uses an OpacityMask with a LinearGradientBrush that starts out at 0.5,1.5 and ends at 0.5, -0.5; that is, the image appears to fade away quickly:

The effect can be seen in this close-up of the rendered image in Figure 5:

363-Fig5_XAML.gif

Figure 5: reflection

To finish up, we’ll add a GridSplitter, telling it which column we want to split. This will allow the user to reallocate the relative space between the list box and the details:

The effect is shown in Figure 6:

363-Fig6_XAML.gif

Figure 6: the gridsplitter

Complete Source

The complete source can be downloaded with this article.