he previous article in this series supplied a grounding in the Windows Presentation Foundation (aka Avalon). In it, you saw how XAML, Cider, and Expression hang together to give you a complete GUI toolbox, and let you create applications such as Microsoft’s “Microsoft Max” demonstration photo management application shown in Figure 1.
|Figure 1. Microsoft Max: The figure shows the user interface for “Microsoft Max,” a demonstration photo management application.|
In this article, you’ll take your Windows client development skills to the next level and build an application that looks and behaves similarly. You’ll explore what it takes to build a rich client application that implements a store catalog. You’ll primarily use Microsoft Expression, which is the most robust XAML/WPF toolkit presently available?and far more sophisticated than the basic Cider XAML editor that ships with Visual Studio 2005. Expression is a wonderful tool, and well worth learning if you are interested in developing Windows Forms applications with XAML, because it provides a powerful design and modeling environment. In fact, you’ll implement the application you’ll develop in this article without writing a single line of code on the client side. The server side, which provides data services to your WPF GUI, will be written using Visual Studio in the usual manner.
|Figure 2. The Catalog Browser Sample Application: Here’s the 2D version of the completed sample catalog browser interface.|
In fact, this appears to be the direction that .NET applications are going to take over the coming years, with development split between the Expression family for client-side development, and the Visual Studio environment for server-side applications. After you’ve read through this article and built your first WPF 2D application you’ll begin to gain a solid understanding of the exciting new tools with which you’ll be able to build the best UIs you’ve ever built?and build them by writing less code!
The sample application is a simple catalog browser for an online store, complete with some nice user interface effects that give it a ‘gel’ 3D interface (see Figure 2). The application also includes an animation where, when a user selects a product, the selected image ‘flies in’ from behind the selection list.
In this article you will build the basic 2D version, which looks and feels like a standard Windows application. The next article will go further, showing you how to spruce the UI up 3D and animation effects to get the full WPF experience.
Building this UI with WPF is very easy?and a great way to start learning how to use the Expression Interactive Designer.
To get started, fire up Expression, start a new project, and select a Windows EXE project type. Expression prepares a new application containing a single scene, called Scene1.xaml, as shown in Figure 3.
|Figure 3. New EXE Application: Here’s how a brand-new EXE application project looks in Expression, with a blank scene.|
The application follows a Master/Details pattern. It will show a list of products on the left. When a user selects an item, it will show the details for that item on the right. To implement an application like this you use a splitter to break the scene into two independent panes. To do that, place a Grid control on the scene and then place a splitter inside the grid. The Grid control is visible in the controls contained in the Library Panel, simply select it and draw out the area that you want the Grid to occupy on the scene.
At the bottom of the screen you’ll see a Timeline panel containing all the elements. Note that?a new Grid has been added. Rename it to ProductGrid. When you select the grid, Expression draws a yellow border around it in the designer, and an additional blue border to the top and to the left.
Hover over the blue border with your mouse and a red bar will appear. This bar will be the location of your splitter. Set it to a place that you are happy with, and click on it to split the grid into two columns. See Figure 4 for an example.
|Figure 4. Splitting the Grid: The figure shows the Expression designer after splitting the Grid into two columns or panes.|
You add content to a pane using the ContentControl control, which acts as a parent to store a single control within the grid.
|Author’s Note: When you want to store more than one control in a ContentControl, store a Panel control within the ContentControl. The Panel can contain many child controls.|
Drag the ContentControl onto the left pane of the Grid.
This ContentControl will form the container for the master list of products you saw earlier. As such it needs to fill its complete pane. At this point it’s good to rename it something such as Master.
Resizing the ContentControl is a little different in Expression/XAML than you are used to in the Visual Studio.NET designer. You’ll need to select the ContentControl and edit its layout properties. If you don’t see a Layout panel near the tools on the right hand side of the screen, drop down the View menu, and select “Layout.” To make the ContentControl fill its parent column, set the Width and Height to NaN, which means “Not a Number” (see Figure 5), its Alignments to Stretch, and its Margins all to zero pixels (see Figure 6).
Next, Manually draw another ContentControl anywhere within the right hand (Details) side of the grid. Name this control Details. As a quick check of where you should be now, refer to Figure 7.
Set the Details control’s layout for Size and Margin in the same way that you set the other one, except in this case, give it a left margin of 20 pixels. This will create a space between the two panes. You’ll put a splitter control in this space which will handle all split and window resizing automatically for you at runtime (you’ll see what this means later if you’re a little lost now)
From the toolbox, select a GridSplitter control and draw it in the space between the Master and Details panes. It should fill in with a rectangle. Remember this is all XAML, so it is vector-graphic based. You can use the zoom tool at the bottom of the scene to zoom in and get more precision when drawing the splitter.
Creating the Business Logic?Binding to Data
Now you have the template that your application is going to be built on. It doesn’t really do much yet, but all that will change in a hurry when you start placing controls and binding them to a data source.
To get started, you’ll need a data source. For the sake of simplicity you’ll be using a flat XML file on your file system as the data store. In the next article in this series, you’ll use Visual Studio.NET to build a complementary data service as well as to create the 3D “Gel” interface that you saw earlier.
But let’s walk before we run. The XML file for this tutorial is included in the downloadable code. It implements the simple catalog that you’ll be using here.
The application that you’ll implement is based on the reference application called “Commerce Starter Kit’ for ASP.NET 1.1.” You can browse and experiment with the original version of this application on the ASP.NET Web site. It is a fictitious store selling silly gadgets that could potentially be used by spies.
Each gadget has a product code, name, description, rating, picture and price. The XML represents the list of gadgets like this:
? Figure 8. The Data Panel. Here's how the Data panel in Expression looks before adding any data sources. ... TCKLR1 Fake Moustache Translatorc:IBuySpyXYZ.GIF Fake Moustache Translator attaches between nose and mouth to double as a language translator and identity concealer. Sophisticated electronics translate your voice into the desired language. Wriggle your nose to toggle between Spanish, English, French, and Arabic. Excellent on diplomatic missions. *** $599.00
|Figure 9. Create Data Binding Dialog: The figure shows the Create Data Binding dialog that you access by clicking the DataContext property in the Properties Palette.|
To bind your application to this data source, the first thing you’ll need to do is (surprise, surprise) create a data source connection.
If you cannot already view the Data panel, select View?> Data. You’ll then see the Data panel shown in Figure 8.
As this is an XML data source, select the “Add XML Data Source?” link. In the ensuing dialog, browse to the XML file (from the downloadable source) containing the catalog information, and give it a friendly name such as “SpySource.”
Next you will tie this to your application by selecting the base grid (called ProductGrid) and then viewing the Properties Palette. On this palette you can see the DataContext property. If you select it, a menu pops up. From this menu you can select “DataBind?” to call up the Create Data Binding dialog shown in Figure 9.
For this application, you want to bind to the Product level of the XML. Select the Data Field button at the top of the dialog, and then expand the nodes of the data source until you reach the level shown in Figure 9; then click “Finish.” The data context of the grid is now the Product level of the data source.
Add and Bind Controls
Now you can add a List control to the Master pane (remember, Master is the name of the ContentControl that you placed on the left side of the grid earlier). The easiest way to do this is to select Master in the Timeline. After it is selected, find the ListBox control in the Library panel and double click it. You’ll see the ListBox fill the Master pane, and appear as a child control to Master in the Timeline. See Figure 10.
|Figure 10. Adding a ListBox: Here’s a partial view of the Expression interface and the Timeline panel after adding the ListBox to the Master Pane.|
You bind a ListBox to data with its ItemSource property, which you can find in the properties palette. When you’re happy with the layout of the ListBox, select the ItemSource property, and from the menu that pops up, select “DataBind.” You’ll be presented with the Data Binding dialog (the same one that you saw earlier in Figure 9).
This time you should select the ‘Explicit DataContext’ binding source button. Remember that the parent grid was bound to the Catalog data source. You’ll be binding to a specific field on this, so we can leave this setting as it is.
However, to create a UI that shows the Master/Details bound data you need to create a ‘Data Template’. At the bottom of the dialog you’ll see a button that allows you to create one of these. Select it, and you’ll get the dialog shown in Figure 11.
|Figure 11. Creating a Data Template: The Create Data Template dialog lets you define reusable data templates.|
This time, you’re interested in the Name element of the data, so that the master list will be a list of product names. To achieve this, clear all the checkboxes except the Name field as shown in Figure 11.
You’ll see that the list gets populated with the names of the products from the XML data source. Before you run the application however, you should set a default item to be selected so that the Details pane will have something to show. You do this by setting the ListBox’s SelectedIndex property. You can set this to 0 to ensure that the top item in the list is selected by default. You should also set the IsSynchronizedWithCurrentItem property to true to ensure that the list stays synchronized with the current context of the data.
You can now run your application and view the contents of the master list with all the products in it. It’s not very interesting though, so let’s add the details.
|Figure 12. Populating the Details Pane: Here’s one possible arrangement for placing the Image and TextBlock controls on the Details Pane|
First, remember that the Details area is a content pane that can hold only one control, so you have to put a Grid control inside it, which can hold many children. Make sure that the details pane (and only the details pane) is selected. It will have a yellow border around it when it is properly selected. If you have trouble with this, double click on it in the Timeline, and it will get selected. Next, double click the Grid control in the Library. That will add a new Grid, sized to fit perfectly within the Details area.
To this Grid control you should add two new TextBlock controls and an Image control. Size and place them anyway you like. You can see an example in Figure 12.
You can bind the TextBlock controls by selecting their Text property and clicking “DataBind?.”
You’ll get the Data Binding dialog which you’ve already seen a couple of times. As you are binding to something on an already-well-known context, you select the “Explicit Data Context” option and then navigate to the relevant field?in this case, bind the TextBlock controls to the Description and Price properties of the data.
|Figure 13. The Running Application: Here’s the sample WPF / XAML Application after selecting an item in the list, showing the image and details in the right hand pane.|
For the Image control, follow the same process, except that you bind to the Source property of the image. The XML data source contains paths to images for the products (the image files themselves are part of the download for this article). You should copy the image files to a directory on your hard drive and make sure that the paths in the XML data match the image locations.
Running the Application
Congratulations, you’ve created your first WPF application, built entirely in XAML using a development tool called Microsoft Expression. To run it, you can press F5 or select “Test Project” under the Expression Project menu. The project will execute (see Figure 13). Note that when you resize it by resizing the Window or moving the splitter bar, all the controls adjust as well, sizing neatly to the current Window and split dimensions.
The next article in this series expands on this application, building a “live” data source in Visual Studio.NET that will provide a hosted catalog for the product, replacing the static XML file you used this time. Also, you’ll spruce up the UI with 3D, animations, reflections and GEL effects. By that time you’ll really be in your element, building Avalon applications and learning how the new units of Expression, Cider, XAML, Avalon, and WPF fit together to allow you to create compelling end-to-end application experiences.