The Mists of Avalon

This article introduces “Avalon,” the exciting new presentation layer of the upcoming Windows version (codenamed Longhorn). I’ll first point out what’s so fundamentally new and advantageous about the way Avalon deals with graphics, and then show you how to use XAMLPad, a tool that comes with the WinFXTM SDK, to get a first taste of Avalon programming.

In the following parts of this article series, you will see how to use Avalon with .NET code in Visual Studio 2005, and also take a look at the more advanced features of Avalon, such as 3D graphics, animation, and speech.

Many think of Avalon as a future technology and part of Longhorn (which is correct), and hence not yet available (which is wrong): The Beta 1 preview is available to the general public for download (the latest version is of May 2005), and by installing the latest WinFXTM SDK, Avalon applications can be developed with the Visual Studio 2005 Beta 2, which is freely available as well. In fact, many software vendors and individual developers are already busy creating Avalon applications on the current Beta platforms, so they are ready when Longhorn is released.

Note: This article is based on pre-release information from the current WinFXTM SDK Beta, so details might still change. This article will be updated as the WinFXTM SDK gets stable and more details are available.

The Old World: Same Procedure as Every Year…

If you have been developing Win32 applications in C or C++ so far, you will most probably be familiar with the GDI (Graphics Device Interface)—Microsoft Windows’ API for device-independent graphics output since 1985. Ever since, the GDI was based on the metaphor of a virtual canvas (the Device Context, or DC), a set of drawing tools like brushes, pens, fonts, bitmaps, and so forth (known as GDI objects) that you could select into a DC in order to use them with the drawing functions (MoveTo, LineTo, Rectangle, Ellipse, TextOut, and so on). The GDI supports basic coordinate translation and scaling, so you could use logical units (like millimeters, inches, twips, or even your own units) for drawing, and have the GDI map them to physical (or device) units, achieving a fair degree of device independence. Ideally, the same drawing code could be used for output to the screen, a printer, or a plotter.

Other Graphics APIs

Just for the sake of completeness: When talking about Windows graphics APIs, the GDI+ (a modernized, more object-oriented revamp of the GDI), OpenGL (an open, multi-platform standard for high-performance 3D graphics, used mostly in scientific visualization and games) and DirectX (an API for direct access to graphics hardware, among others) should not pass unmentioned—all three are alternative, but, with regard to the GDI, much less used graphics APIs available under Win32.

Procedural Drawing

In any case, drawing with the GDI has always been a procedural (or imperative) activity: You wrote code in your favorite language (most probably C or C++, because Visual Basic doesn’t directly support GDI calls) and told the GDI, step by step, what to do to get your GUI to look the way you want. It’s somewhat like standing next to an artist and giving her instructions:

“Please pick up the blue pen—no, the thick one.”

“Okay, now draw a horizontal line across the canvas, at about one third of the canvas height from the top border—leave a margin of half an inch to the left and right.”

“Fine. Now put down the blue pen, and pick up the bright red one.”

“With that pen, please draw a circle with a bounding rectangle that starts at 4.57 inches from the left and 3.2 inches from the top, and a radius of 2 inches.”

“Okay, now take the yellow brush…”

Sounds tedious? It is, but that’s the way procedural drawing works (and if you forgot to put down the blue pen, you were eventually arrested by the GDI resource police for stealing pens, and punished with a system crash…). The good news about procedural drawing is that it is flexible; for example, the instruction in the above example “one third of the canvas height” can be easily expressed as an arithmetic construct in any programming language—and hence, the actual position of the line can be made dependent on the current height of the canvas (your window’s client area). This is what a typical WM_PAINT handler in Win32 SDK code could look like (it just draws a horizontal line at one third of the client area’s height, leaving a margin of 30 pixels to the left and right, and using a blue, four-pixel-wide pen:

case WM_PAINT:
  {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);

    // Get our canvas size:
    RECT rcClient;
    GetClientRect(hWnd, &rcClient);

    // Vertical position is at one-third of the height:
    int lineYPos = (rcClient.bottom - rcClient.top) / 3;
    int margin = 30;

    // Create and select blue pen
    HPEN hBluePen = CreatePen(PS_SOLID, 4, RGB(0, 0, 255));
    HGDIOBJ hOldPen = SelectObject(hdc, hBluePen);

    // Draw the line
    MoveToEx(hdc, rcClient.left+margin, lineYPos, NULL);
    LineTo(hdc, rcClient.right-margin, lineYPos);

    // Clean up...
    SelectObject(hdc, hOldPen);
    DeleteObject(hBluePen);
    EndPaint( hWnd, &ps );
  }
  break;

What’s more, you can use conditional statements (in the case of an error message, use red color for the text; otherwise, black) or loops (you can draw a grid, say, a checker board, by drawing lines or squares in two nested loops, calculating the coordinates from the loop indexes). So, although flexibility is the major advantage of procedural drawing, one of the drawbacks is certainly that it requires you to break down the entire drawing code into fine-grained steps—everything needs to be said explicitly and in great detail.

Now, how would it be if, instead of giving step-by-step instructions, you could simply provide a sketch of the drawing, and have the artist elaborate on that? You could even decide about how detailed the sketch would be—either make the sketch rather… well, sketchy, and let the artist put her creativity into the details of execution, or, on the other end of the spectrum, provide a very detailed sketch and leave little room for interpretation. Like the idea? Then, welcome to the world of declarative graphics programming!

Declaration of Independence

The declarative approach is, to some extent, the exact opposite of the procedural one: Instead of specifying how you want something to be done, you rather specify what you want as a result, and leave it up to the executing instance how exactly it fulfills your request. A familiar example of a declarative description is a Web page that you might design in HTML (HyperText Markup Language): You define the logical structure of your document, including headers, sub headers, paragraphs, tables, emphasized text, and the like, but it is up to the browser on the client side how exactly the page will be rendered. If you like, you can of course get into more detail and also specify font sizes, positions, and exact spacing for table cells—the point is that you can, but need not be so explicit.

In the IT world, we encounter the dualism between the procedural and the declarative paradigm all over the place. For example, a macro in Excel (which typically consists of instruction sequences, like “select a range of cells, copy them, move the cell cursor to another place, paste…”) is procedural. An Excel formula, OTOH, is declarative: You just specify that you want the sum of a range of cells, divided by the number of months to appear in the cell where you put the formula, and leave it up to the spreadsheet’s calculation engine how, and, more specifically, in which order to perform the calculation steps that lead to the desired result. By the way: The declarative nature of spreadsheet formulas has been one of the major reasons for the enormous success of spreadsheet applications like VisiCalc, Lotus 1-2-3 and later Excel, because they allowed users to create solutions tailored to their needs without having to learn how to program. To non-programmers, it is much more natural to specify what they want instead of explaining step by step how they want it to be done.

Almost all of the more widely used programming languages are imperative—two prominent exceptions being Prolog and LISP, which are both declarative languages.

Note: As with most dualisms, there is no hard dividing line between “procedural” and “declarative;” some approaches are more procedural (they usually rely more on code) whereas others are more declarative (which normally means less code and more data). One of the main advantages of the latter is that it is much easier to build editors and other tools for declarative data—but I’ll come back to that in a moment.

Introducing Avalon

Okay, now where and how does Avalon come in? “Avalon” is the codename for the presentation subsystem of WinFX, an extension of the .NET 2.0 Framework, and the new application programming model for the upcoming release of the Windows OS, currently only known as “Longhorn.” Longhorn’s release to the market is scheduled for mid 2006, and plans are to make WinFX available for Windows XP and Windows Server 2003 as well in early 2006.

For those of you interested in trivia: “Avalon” is the name of a legendary island somewhere in the British Isles. According to the legend, it’s the place where King Arthur’s body is buried. The title of this article refers to Marion Zimmer Bradley’s novel, The Mists of Avalon, which tells the King Arthur myth from a feminist point of view. However, Avalon is also the name of a peninsula in Newfoundland, and that’s probably where the name for the Avalon subsystem comes from: Recently, Microsoft tends to use names of geographical locations in the American North-Pacific as codenames for upcoming products and technologies. By the way, “Longhorn” is a saloon in the Whistler-Blackcomb ski resort near Vancouver, and both “Whistler” and “Blackcomb” are codenames as well (for XP and Longhorn Server, respectively). Guess where the Microsoft OS guys hold their design retreats…

Because “Avalon” is a codename, Microsoft puts it in quotation marks in most of its publications. For the sake of simplicity, I will omit the quotation marks for the rest of this article.

The Three Pillars of WinFX

Applications taking advantage of WinFX rest on three subsystems, often referred to as the pillars of WinFX: Avalon (the presentation layer), WinFS (file system and data services), and Indigo (communication services):

Although Avalon and Indigo will be included in the Longhorn Beta 1 announced for summer 2005, WinFS didn’t make it and will be added later. This article series focuses on Avalon, the leftmost pillar.

All the capabilities of Avalon are exposed through a managed object model that can be manipulated from any language that supports the CLR (Common Language Runtime). The current Beta 2 of Visual Studio 2005 only allows C# and Visual Basic for creating WinFX applications (so much for a “common” language…)—hopefully, the final release will support C++ as well.

We will soon start to be seeing applications with very fancy and impressive Avalon user interfaces, so it’s probably a good idea for developers to get prepared for the new world of UI programming as early as possible (that’s precisely why I wrote this article—and probably also the reason why you are reading it).

A major difference between Avalon and the GDI is—you will have guessed it by now—that Avalon uses a declarative model to describe graphic entities of any kind: Windows, Web pages, layout panels, vector graphics, reusable controls, animations, 3D objects, and sceneries…. Everything can be built in a declarative manner.

The Object Tree

Graphics output in an Avalon application is not achieved by a series of sequential instructions, but rather by providing a hierarchy of objects, along with their properties, from the Avalon class model. So, instead of saying “pick up a three-pixel-wide red pen, pick up a yellow, solid brush, draw a circle using the current pen for the border and the current brush to fill it,” you would rather say: “We have a window. The window contains a canvas. On the canvas, there is a circle. Ah, and yes, the circle’s border is red, and it is filled in yellow. You want to know how thick to draw the border? Three millimeters—unless otherwise specified.”

Any graphics scenario in Avalon is constituted by a hierarchy of objects from the Avalon object model: the object tree.

A very simple object tree might be depicted like this:

At the heart of Avalon, there is a compositing, vector-based rendering engine that takes full advantage of the hardware capabilities of the installed graphics adapter (allowing for effects like free scaling, 3D shading, transparency, alpha blending, specular reflection, animation, video, and so forth) to interpret the object tree and render the scenario. However, let’s approach it slowly: No 3D, no animation here for the moment: This is what the output might look like when the above object tree is rendered:

In addition to simple geometrical shapes, the Avalon class model includes all sorts of controls like edit boxes, labels, buttons, combo boxes, checkboxes, list controls—everything you now know from MFC or Windows Forms, and much more. However, all those controls are defined as vector graphics—so instead of getting “jagged” when resized, they scale nicely to every possible screen resolution and size. Avalon is mainly vector-based (I say “mainly” because bitmaps and video movies, which are pixel-based, can be integrated as well).

Essentially, the UI of an Avalon application can be built by creating an object tree of GUI elements. In that case, the object tree is often referred to as a UI tree.

A simple UI tree might be depicted like this:

When rendered by the Avalon rendering engine, the output might look similar to the following:

Because all the UI elements are vector-based, the window containing them can be easily resized, and the controls will grow and shrink or rearrange accordingly. Styles can be applied at any level, changing, for example, the font used for all elements, or just the border color of certain buttons.

Even data binding can be added in a declarative manner: You can associate certain controls with data sources like an SQL database or RSS feeds, and when it comes to displaying the controls, the contents will be automatically supplied from those sources—without writing a line of procedural code!

You can create and modify an object tree (or, more specifically, a UI tree) in much the same way you deal with other .NET objects: by using any CLR compliant language (like C++, C# or Visual Basic) to instantiate objects from the .NET class library, setting their properties, and calling their methods. Now, you might wonder where the benefit is, and why all the fuss about declarative drawing? After all, you still need to use a programming language and lastly call procedures to get something displayed.

Hold on—there’s more to it. Programmatically creating the UI tree is just one way of doing it (and I will discuss it in an upcoming article). The other is… XAML.

Meet XAML

XAML (pronounced “zammel”) is a markup language based on XML that can be used to build an Avalon object tree. XAML is short for eXtensible Application Markup Language. (Surprisingly, the “A” in XAML doesn’t stand for “Avalon,” but for “Application:” That’s because in the future, we won’t only be using it for describing Avalon scenarios, but .NET object hierarchies in general. Keep this in mind—one day, you will understand the impact of this statement.)

The following XAML code represents a UI tree and will produce the output shown above:

<Page xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
      Name="Page1">
  <DockPanel Background="Bisque" Name="OuterPanel">

    <StackPanel  Background="LightBlue" DockPanel.Dock="Top"
                 Margin="10,10,10,10">
      <TextBox   HorizontalAlignment="Left"
                 Height="24px"
                 Width="2.6 cm"
                 Margin="20,10,10,10">Text selection</TextBox>

      <Button    HorizontalAlignment="Left"
                 Height="30px"
                 Width="100px"
                 Margin="20,10,10,10" Name="Button1">Copy</Button>
    </StackPanel>

    <Label VerticalAlignment="Top">Select Country:</Label>
    <ComboBox VerticalAlignment="Top"
              Height="24px"
              Width="100px">
              IsSelectionRequired="True">
      <ComboBoxItem>France</ComboBoxItem>
      <ComboBoxItem>Germany</ComboBoxItem>
      <ComboBoxItem>Italy</ComboBoxItem>
      <ComboBoxItem>USA</ComboBoxItem>
    </ComboBox>
  </DockPanel>
</Page>

The XAML tags correspond directly to the objects in the UI tree, with attributes describing their properties, and the tag data representing the textual content of the visual elements. For example, the following Label tag maps to a Label object with the VerticalAlignment attribute set to “Top”and with “Select Country:” as the content, which is the textual representation that the users will see:

<Label VerticalAlignment="Top">Select Country:</Label>

Panels

Panels have no text content of their own: They are rectangular containers for other elements (like text blocks, buttons, controls—and other panels). Panels come in seven flavors, all with their own specific layout properties: BulletPanel, Canvas, DockPanel, Grid, StackPanel, TabPanel, and ToolBarOverflowPanel. Panels can be deeply nested to obtain a very fine-tuned, yet flexible, layout. If that reminds you of tables in HTML, you’re only partially right: HTML tables were originally introduced to provide a logical structure for tabular data, arranging it in tables, rows and cells; however, tables have ever been misused by Web page designers for layout purposes, leading to countless problems with the way tables were interpreted and displayed by different browsers. In contrast, Avalon panels have been designed with layout in mind—and by choosing which level of detail you specify as the attributes for panels (like absolute sizes or margins), you can decide to which degree the layout should be fixed or free-flowing depending on the run-time requirements. In short: Avalon panels are meant to do what HTML tables have been long misused for—and much more.

Of course, there are corresponding XAML tags for all the other types of controls from the Avalon class hierarchy: buttons, text boxes, combo boxes, list controls…

Dialog Resources

“But wait,” I hear you say, “that way of describing a user interface reminds me of dialog resources in classical Win32 SDK and MFC applications!” And again, you’re partially right. Indeed, dialog resource templates have been a strong declarative component in classical Win32 applications (which I’ve left—purposefully—unmentioned in my introduction about procedural UI design). Instead of writing code for creating a dialog box and adding child controls to it, you could “draw” parts of your UI in a resource editor. At run-time, Windows would create the resulting dialog window with all child controls for you and handle a lot of stuff automatically:

  • Dialog resource templates are designed using “dialog units”—virtual units that are appropriately transformed to device units (pixels) at run-time, depending on the system base font size that the user had selected in the “Display” control panel.
  • The background of dialog windows is painted automatically, again according to system-wide settings the user made.
  • Certain keys (like tab or arrow keys) are automatically handled according to the tab order and geometrical layout specified at design time.

Resources and Localization

Look for a moment at the motivation behind all this: The resource concept has been invented (not by Microsoft, by the way, but by Apple when they first introduced Lisa, the predecessor of the Macintosh, in 1983) to simplify the localization of applications to different countries and languages (now fancily called “cultures” in .NET-speak). An obvious first step is to put any text a user would see not as hard-coded strings into the program’s source code, but to keep it in a special data section in a well-defined format so that it could easily be extracted and modified from a compiled executable by using appropriate tools (resource editors or more specialized localization tools); the idea was to be able to translate every textual element of an existing application without having to modify the source code. It soon became obvious that merely translating text strings only did half the job: Text differs significantly in length between various languages. For example, French text is 30% longer in average than the corresponding English text. A button labeled “Open File” would become “Ouvrir fichier” in French; that’s 14 characters instead of 9 (a 55% gain!), and chances are good that a button designed to hold the English text would be too short for the French translation. In Italian, it would be “Aprire archivio” (+66%), and Finnish or Hungarian texts are usually even longer. That’s why the resource concept was soon extended to entire dialogs and their layout: Now translators, instead of merely translating text, could use tools to adjust the layout of dialogs and the sizes of controls so that the translated text would fit nicely. By the way, similar ideas led to bitmaps and icons ending up in resources as well: Certain pictograms or visual representations of objects (and even colors) can have different meanings in different cultures.

However, the concept of resources ends with menus and dialog boxes: The central parts of the UI of most applications need to be much more flexible than dialog resources allow for, and typically can’t be built with a resource editor, but have to be coded procedurally, creating controls and child windows by appropriate API calls, and, as mentioned at the beginning of this article, by drawing significant parts of the UI with procedural GDI calls. Needless to say, that kind of code uses either hard-coded strings and fixed element positions (and hence those applications are impossible to localize with a resource editor), or have to be coded in an extremely flexible way, loading any user-visible text from string table resources, and making the size of procedurally created UI elements depend on the actual text length at run-time. I know, because you are all conscientious developers, you will say “So what; that’s the way I’ve learned it and always done it—of course I keep all my strings in resources!” Heck, of all real-world Windows projects I’ve seen do far, only about 5% were coded by the textbook. The remaining 95% used hard-coded strings and fixed element positions, making them impossible to localize without modifying the source code.

In other words: A high ridge went through the UI code in classical Win32 applications: On one side, you had the parts designed as resources (declarative!) that were easy to create and localize and had many aspects handled automatically at run-time, and on the other side, the parts that required more fine-tuned control by the developer and hence were coded procedurally—either requiring an enormous extra effort to keep them flexible enough for localization, or completely neglecting that requirement.

But where did I leave off before talking about resources? Ah, Avalon. Its declarative nature makes an important difference in several aspects: Instead of limiting itself to certain trivial and mundane parts of the UI like menus, dialog boxes, and accelerator keys, almost the entire UI of an Avalon application can be designed in a declarative way! This leads to a couple of advantages:

  • Localization: As you have seen, all user-visible text strings in XAML (“zammel”, remember, not “ex-ay-em-el”) are defined as tag contents. That makes it fairly easy for localization tools to extract and replace those contents by their translated versions. Furthermore, the use of automatic size and layout (buttons that automatically resize to fit their text content, flowing panels, and so on) remove the need to manually change the layout when text lengths change. Avalon’s rendering engine will take care of that at run-time. I agree that normally there’s no such thing as a free lunch (the TINSTAAFL principle)—but here, you really get the best from two worlds: All the advantages of the easy, but inflexible dialog resource editor layout, combined with automatic resizing and reflowing at run-time—and this time, you don’t have to code it yourself; it’s already there.

  • Accessibility: Because all textual elements of your UI will be present in a declarative, hierarchically structured form (as data) instead of code, it will be fairly easy to make the contents available to people with disabilities (as an example, think about blind or sight-impaired persons who currently use text-to-speech screen readers or Braille keyboards to get access to Windows applications or Web pages). Although texts in controls are fairly easy to read out, current screen readers use all kind of dirty tricks (like GDI hooks or on-screen OCR) to grab the contents of text drawn into windows on the screen. With GUIs created in Avalon, a consistent and documented interface will be available to access any textual content at run-time. But not only speech output will benefit from the way Avalon stores text content: A very recent addition to WinFX are the speech recognition .NET classes; these provide a managed interface to voice recognition and grammars. They allow for completely speech-enabling an Avalon application by adding a few lines of code to the code-behind file, and without any further coding of your own, users can use voice commands to navigate a form, check options, and enter values into text boxes! You will see in one of the next articles how exactly this can be done.

  • Tools: Here comes one of the major advantages, at least in my opinion, of Avalon’s declarative way to store most of what makes a GUI in XAML format: It is very easy to build tools that generate declarative data. That means that you will be able to draw most of your UI—and not just dialog boxes, as it was the case with classical Win32 API programming—with interactive, visual editors. Visual Basic (and now also the Windows Forms elements from .NET 2.0) already go a large step farther into that direction, by allowing you to create a significant part of your UI in a declarative way—most of it, but not all. Although toolbars, status bars, and panes (for free-flowing layout) are already present in the .NET toolbox, today’s declarative programming stops when it comes to geometrical shapes, auto-resizing buttons, and complex graphics objects (let alone 3D). With Avalon, all this will be possible.

    You might say: Well, what’s so hard about writing a tool that lets me draw a complex graphics scenario and outputs procedural code to draw that? You’re right, generating code is not so much a problem—but a true editor can’t only be a one-way tool that creates code; it also must be able to reverse the process: Read in existing code and allow you to edit it interactively. And, although this is can be a real challenge with procedural code, it’s a piece of cake with XAML (or any other kind of declarative, standardized format, for that matter). Expect not only to see GUI-builder tools, however: Localization tools (as they exist now for resources), tools that convert existing UIs from various formats like resource templates, HTML, 3270 terminal screens, Postscript, and so on to XAML will soon appear on the horizon. Modeling tools for creating complex 3D scenarios with lighting, shading, and animation are already there: For example, ElectricRain’s ZAM3D is a very advanced 3D modeling tool that can export its 3D scenarios to XAML—you can download the current beta for evaluation here.

    Update: I read today that Microsoft’s Mike Swanson has just written a converter that exports Adobe Illustrator graphics to XAML; it’s an Illustrator plug-in, and you can download it from http://www.mikeswanson.com/XAMLExport/. For those who don’t know: Illustrator is one of the most important vector-based tools widely used by designers throughout the industry for creating illustrations and logos.

  • Design: This can’t be emphasized enough, but it is actually one of the fundamental benefits of Avalon: In classical Win32 UI design, the developer (yes, that’s you) already gave away part of the responsibility for the appearance of the UI to translators or localization experts by keeping certain portions of the application in resources, allowing for their modification without access to the source code (and hence without requiring the developer’s intervention). In this regard, Avalon goes much farther: Ideally, it puts the entire UI into XAML markup, allowing not only translators, but designers (yep, those guys with the strange haircuts who usually draw the fancy bitmaps you have to load and display in your code via StretchBlt, who tell you which fonts and RGB colors you have to use, and who make the Web pages to sell the product you’ve been working on so hard) now can, by the use of appropriate tools (no, they don’t have to learn XAML) create most of your app’s UI.

    (Pause, take a deep breath, preferably from an oxygen mask…)

    Now, if you are a UI guy like me and have always put much of your C++ coding skills and deep GDI knowledge into creating cool user interfaces, this vision will probably scare the hell out of you. But, if you belong to the vast majority of developers I’ve met so far, you will be more than glad to hear that, finally, designers will take over the job of creating the visual aspects of the GUI (that tricky stuff with colors, fonts, and coordinates, remember?) and let you concentrate on the important aspects of your application—the logic behind the scenes. For the rest of us: Well, they still need someone to develop the tools for the designers…

    Seriously, the advantage of putting the UI design into knowledgeable and skillful hands should be obvious. And still, you don’t have to completely give up control: Remember the high ridge I mentioned between resources (declarative) and procedural UI design in classical Win32 programming? Well, Avalon turns this high, solid ridge into a soft, flexible sand dune. You’re absolutely free to decide how much of your UI is done in XAML, and how much you do procedurally. You can create UIs with zero lines of C#, you can create UIs with zero lines of XAML, and everything in between. (Although zero lines of both will probably qualify for poor UI design).

To summarize, the real power of XAML in Avalon applications is based on two different levels of abstraction: The first is the abstraction of the business logic (usually written in procedural code-behind) from the visual representation supplied declaratively in XAML (which separates logic from presentation), whereas the second level is the abstraction of the text content from the visual representation, separating design from content and hence allowing for easy localization and data binding.

XAML in .NET Applications

When you create an Avalon application with XAML, one or more files with XAML code will be included in your Visual Studio project, and get compiled to a binary format (BAML) which is added to your assembly as a resource.

An important thing to note is that with XAML code it is not only possible to describe a static scenario (like HTML, Postscript, or GDI Metafiles), but include dynamic effects like animation and even event handling code (more like DHTML or HTML with embedded VBScript or Jscript). If you are familiar with ASP, you will know the idea of code-behind files—actually, a similar concept is normally used with XAML, where the XAML file is compiled to a partial .NET class, and additional .NET code that you can supply will handle the aspects of the GUI which are not described in XAML.

Actually, the comparision to HTML is not so bad: Creating a user interface in XAML is very similar to building a Web page in HTML. However, XAML goes far beyond the capabilities of HTML in that it adds very advanced 2D and 3D vector graphics, storyboard- and timeline-based animation, data binding, event handling and speech recognition and synthesis.

More by Author

Must Read