I presented a session on WPF at the Arizona .NET User's Group last night, and today have been getting email and calls from several people who wished they could have been in attendance, and wanted to get started with WPF. So for those that weren't there last night, this post is designed as an intro to get you started.
The version of Windows Presentation Foundation (WPF) included in the June CTP is very polished. Being this late in the development cycle, the things you learn now in this environment will probably not change very much before it goes RTM. As well there's many fewer bugs compared with even six months ago. I've been very impressed with the reliability, anyway. The same exact bits from this drop are going into the next CTP of Vista. So altogether it is now a great time to start experimenting with WPF. This post offers a minimalistic approach to dive straight into rendering XAML on an XP machine by using the neat-o test interface called XamlPad:
(DonXml's analog clock example converted to work with the June CTP bits.)
Prerequisites you probably already have installed:
- For Windows XP, SP2. Or if you're running Win2K3 Server, SP1. Vista Beta2 will work as well with no additional hotfixes.
- .NET Framework v2.0 (22 megs)
- DirectX, at least version 9.0c (36 megs. You need this later “c” rev so that it also includes the DirectX for Managed Code update.)
You probably installed all these like eight months ago when they came out, right? If not then be sure to put them onboard before going further. Notice that you don't need Visual Studio installed to experiment with XAML.
Normally you would have to download the gigabyte-sized Windows SDK in order to get to the point that you can use XamlPad. But in the interest of streamlining everything, I've put all the specific stuff you need into this tidy 11 meg .ZIP:
Once it's extracted, install these two in this order:
- wpf.msi (This is the RC1 build of the Windows Presentation Foundation portion from the June CTP of .NET 3.0. This takes about 6 minutes to install on an average system, mostly because it does a bunch of ngen during the install to optimize everything for speed.)
- WIC_X86_ENU.exe (The Windows Imaging Component update that is required to use WPF. Really small. This takes about 20 seconds to install. Without it you won't be able to display images in a XAML panel.)
If you have a really lame video card that does not support DirectX 9 then you will need the to fake out DirectDraw support by installing RGBRAST. And in that case you won't be able to do any really cool 3D animations and transforms. But that is probably only like two of you out there. For everyone else, you're already all set with what you need.
With that, you can now directly run XamlPad.exe, which is also found in the .zip. And if all goes well, you'll be presented with XamlPad showing a blank screen. So what's next? I guess the first thing is a simple “Hello World”. Looking at the lower markup panel in XamlPad, you have a <Page>element, and inside that a <Grid>element. It's tempting to think that this is just a re-hash of HTML. But these elements actually represent .NET types. Unlike the very forgiving environment of HTML, XAML is case-sensitive, and also gets really cranky if you don't properly nest objects. For instance, if you try typing “Hello World” directly in there, it complains that you can only put in objects of type UIElement inside this UIElementCollection. The Grid itself is really a System.Windows.Controls.Grid. The things you add inside become part of a public property it exposes called Children. So you can see that in every respect XAML is very closely tied into the .NET framework, as it instantiates objects the same as you could have done in C#. To put some text out there, we should be using a System.Windows.Controls.TextBlock object. Simply add this:
Not too exciting yet, but at least it does the job. Let's now try to add another TextBlock and see what happens.
<TextBlock>Well hello to you, too!</TextBlock>
Note that the new text is overlaid directly on top of the first text we wrote!
The reason for the overlap is that the pieces are being rendered in the same cell of this grid. We could get our hands dirty and define some columns and rows, but instead let's use a different kind of panel than the default <Grid> that XamlPad includes for us. Change it to be a <StackPanel>, and the two objects will be stacked vertically, looking as you might have expected it to.
There are several kinds of panels we can use. In addition to Grid and StackPanel, there is Canvas, DockPanel, TabPanel, ToolBarPanel, VirtualizingPanel, and VirtualizingStackPanel. Okay, there are a couple others that are a little esoteric, like UniformGrid and ToolBarOverflowPanel. Each has a little different way of rendering the controls that make their way into its Children collection.
Regarding the TextBlock, the text we typed between the element tags becomes a part of the default property of the System.Windows.Controls.TextBlock object, which is Text. We can also add attributes to define how things look, the same way that we use ASP.NET server controls. For instance, we can spice up the presentation with a larger font and some color by adding these attributes in a TextBlock element:
Note that the color designation has eight hexadecimal digits. What's that all about? Normally in HTML you use six, which translates into three bytes of information for red, green, and blue respectively. In this case we have four bytes, and the first is the “Alpha” channel, which defines the level of opacity that this text will have. This example color is a completely opaque orange.
So with this XAML code as a starting point, you can write event handlers and other logic. It's possible to dynamically add in controls using C# or VB.NET. No longer do we have to bend over backwards to translate objects for presentation. For instance, the majority of what ASP.NET does for us is to bend .NET objects into a format that can be presented in an HTML browser, providing all the funky persistence mechanisms that are necessary like ViewState and cookies. It's a great solution if you're sending content to a browser, but often forces you to know some HTML tricks to get things rendered just right. In contrast, WPF offers a clean presentation environment designed to integrate perfectly with .NET, so in this environment all interaction with the user is done directly with .NET objects.
One of the interesting things that you can do with XAML with 100% declarative code is create animations. Here is a sample block of XAML you can paste in XamlPad to have the analog clock pictured at the top of this post:
It was originally written by Chris Maynard and Don Demcsak in SVG, and then Don ported it to XAML in early 2004. As far as I know it hasn't been upgraded since then... Until today when I took some time and worked out the kinks so that it would display properly with the latest bits. (The animation part had to be totally re-done.) Anyway, from this you can get the feel as to the code that's used to make the sidebar clock gadget in Vista, and what it looks like to write declarative code with animation.
A final note about .NET 3.0: Up until now when you install the .NET framework all the DLLs get stashed in C:\WINDOWS\Microsoft.NET\Framework. Although some features for rasterizing content are still placed in DLLs there, the .NET assemblies we program against from managed code now have a new home: C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0. In that folder you can find a plethora of functionality. For instance, all the types in the System.Windows.Controls namespace used by WPF are found in PresentationFramework.dll. So by adding a reference to that DLL or opening it up in Reflector, you can start getting to know how it's all organized. If you want to quickly see how the inheritance is organized then just use my Assembly Hierarchy Explorer program to navigate through and take a look at all the contents. (Compile the program in VS2005, run it, and use the menu option Assemblies / Open From File.)
Hope that you've enjoyed this introduction to XAML. For a video walkthrough of more XAML features you can test in XamlPad, check out this great screencast done by Tim Sneath that's out on Channel 9. It's a little dated... He did this back in September of last year. For instance, he uses the now-defunct TextFlow element. Replace that instead with the FlowDocument and some Paragraph elements if you are following along with his code. Same kind of thing with some of the Rotate tricks he does. Also note that you must have Media Player 10 or later installed if you want to use video snippets in your XAML.
Next time: integrating XAML with C#. If you want to get a head-start on things then on a system in which you have WPF installed, also install the Orcas updates for Visual Studio, and then check out some great free samples.