Ziff-Davis Enterprise 
DevSource: Microsoft Developer Resource
Add OnsArchitectureLanguagesTechniquesUsing VSForums
 
Home arrow Using VS arrow Working With Avalon Today: Getting Started With XAML
Working With Avalon Today: Getting Started With XAML
By Nick Chase

Rate This Article:
Add This Article To:
Working With Avalon Today: Getting Started With XAML
( Page 1 of 2 )

You don't have to wait for Longhorn to start playing with XAML. Nick Chase shows how to use XAML to create a window, add vector graphics to it, and bind those graphics and their events to .NET code that writes and reads a file on the user's local machine.

I've never much liked the process of taking something as visual and operating system-specific as a Graphical User Interface and coding it with an application, so when I heard about XAML, I was pretty excited. XAML is the code name for Avalon, Longhorn's new markup language, and it enables you to create real Windows GUI interfaces using XML markup.

Fortunately, you don't have to wait for Longhorn to start playing with XAML. In this article, I'll show you how to use XAML to create a window, add vector graphics to it, and bind those graphics and their events to .NET code that writes and reads a file on the user's local machine.

ADVERTISEMENT

This article assumes that you are at familiar with at least one programming language. I'll be using C# in the examples, but the actual code is fairly simple. Similarly, familiarity with XML will be helpful, but isn't required. My purpose here is to give you a general overview of the process of writing XAML applications, as opposed to the nitty-gritty of individual objects.

You must have, at the very least, Microsoft .NET Framework 1.1 and an XAML-capable environment, such as Longhorn or Xamlon.

The Basics

Unless you've got your hands on Longhorn, the first thing you'll have to do is download software that can interpret the actual XAML. One good example is Xamlon, which provides not only a XAML viewer and the various DLL's necessary for making things work, but also two different options for XAML development. Xamlon integrates with Visual Studio so you can easily add XAML to your projects, but for the more text-inclined (such as myself), it also includes XamlPad, a NotePad-like application that lets you quickly preview your results.

(I use XamlPad for the examples, but the code is the same for Visual Studio. You can get a quick start on creating an XAML project at http://www.xamlon.com/docs/Q10046.htm.)

So, let's get started.

Install Xamlon and open XamlPad. By default, it provides you with a new blank file. Start by creating the window that will contain all of your other elements:

<?xml version="1.0"?>
<Window xmlns="http://schemas.microsoft.com/2003/xaml"
    Width="310" Height="285">

</Window>

Just to make sure everything's working, press F5 to preview the document. You should see a plain window, as in Figure 1.

Now you can start adding actual graphic elements. You'll be adding multiple elements, so create a canvas to hold them:

<?xml version="1.0"?>
<Window xmlns="http://schemas.microsoft.com/2003/xaml"
    Width="310" Height="285">

  <Canvas>
     <Rectangle RectangleWidth="300" RectangleHeight="255"
            Fill="Yellow" Stroke="Red" />

     <Ellipse CenterX="150" CenterY="95"
              RadiusX="100" RadiusY="75"
              Stroke="Blue" />

     <Text FontSize="36" 
            Canvas.Left="50" Canvas.Top="175">Hello, world!</Text>

  </Canvas>

</Window>

Let's take a look at what we have here. First off, as I said, a Canvas acts as a wrapper for multiple objects. In this case, those objects are a Rectangle, Ellipse, and Text object. Each object has its own properties, specified as attributes. Some properties, such as RectangleWidth or CenterX, are specific to a particular kind of object. Others, such as Stroke, which outlines the object, are general presentational properties shared by most of the graphics you'll use.

In figure 2, you can see how they all come together.

These are, of course, pretty simple objects; you can also use the Polygon, Polyline, and Path elements to create more complicated structures.

Before I move on, let me talk for a moment about sizes and positioning. Some things are simple, such as positioning the Text relative to the left and top edges of the Canvas using the Canvas.Left and Canvas.Top attributes. As in the case of the CenterX and CenterY coordinates, the origin, or (0,0), is in the top-left corner of the window.

On the other hand, the hyper-observant will notice that the size of the Window in pixels is 310 by 285, but the Rectangle, sized at 300 by 255, fills it. It's not that the Rectangle automatically stretches to fill the Window. That can be done, but it isn't what's happening here. What's happening here is that the Window dimensions refer to the outside edge of the window, rather than the content area, so five pixels to the left, right, and bottom, and 25 at the top are taken up by the actual window display. That might seem silly, but the advantage is that you can actually remove the title bar and border from the window by setting the FormStyle. If we did that, however, we'd have to replace the functionality we're removing, such as the "close" button, so that's a talk for another time.

Gradients and Other Decorations

At this point, you've created a simple but nice display with only a few elements and attributes, and decorating them isn't much more complicated. Attributes can take care of simple things, such as controlling the shape of the rectangle or the size of the line that encapsulates it:

...
  <Canvas>
     <Rectangle RectangleWidth="296" RectangleHeight="252"
            Fill="Yellow" Stroke="Red"
            RectangleLeft="3" RectangleTop="3"
            StrokeThickness="5"
            RadiusX="30" RadiusY="20" />

     <Ellipse CenterX="150" CenterY="95"
              RadiusX="100" RadiusY="75"
              Stroke="Blue" />
...

I've rounded off the corners of the box by setting the RadiusX and RadiusY properties, and set the StrokeThickness to 5. Note that the edge of the rectangle is in the middle of the stroke, so I've also had to adjust the size and position slightly. You can see the results in Figure 3.

Some properties are a little more complicated to set. For example, I used the Fill attribute to set the color of the rectangle, but by using elements, I can create a more complicated Fill for the Ellipse:

<?xml version="1.0"?>
<Window xmlns="http://schemas.microsoft.com/2003/xaml"
    Width="310" Height="285">
  <Canvas>
     <Rectangle RectangleWidth="296" RectangleHeight="252"
            Fill="Yellow" Stroke="Red"
            RectangleLeft="3" RectangleTop="3"
            StrokeThickness="5"
            RadiusX="30" RadiusY="20" />

     <Ellipse CenterX="150" CenterY="95"
              RadiusX="100" RadiusY="75">

         <Ellipse.Fill>
             <LinearGradientBrush>
                <LinearGradientBrush.GradientStops>
                  <GradientStopCollection>
                    <GradientStop Color="Red" Offset="0" />
                    <GradientStop Color="Yellow" Offset="1"/>
                  </GradientStopCollection>
                </LinearGradientBrush.GradientStops>
              </LinearGradientBrush>
         </Ellipse.Fill>

     </Ellipse>

     <Text FontSize="36" ID="message" 
            Canvas.Left="50" Canvas.Top="175">Hello, world!</Text>

  </Canvas>

</Window>

Notice that the Ellipse element is no longer empty. Instead, it contains the definitions for properties that control how it looks. In this case, I se the value for the Fill property, but instead of doing it as an attribute, I'm creating a more complex definition using elements.

Because I essentially want to paint something — the inside of the Ellipse — I use a specific type of brush, the LinearGradientBrush. A gradient is a gradual progression from one color to another, so within that brush I define the stops, or individual colors and where they appear. The Offset of 0 means the gradient starts with Red, and the Offset of 1 means it finishes up at Yellow, as you can see in Figure 4.

Gradients are fun, and you aren't limited to just two colors. For example, you can create a RadialGradient that flows out from the center of the ellipse and passes through multiple colors, like this example borrowed from the Xamlon samples:

...
     <Ellipse CenterX="150" CenterY="95"
              RadiusX="100" RadiusY="75">

         <Ellipse.Fill>
             <RadialGradientBrush>
                <RadialGradientBrush.GradientStops>
                  <GradientStopCollection>
                    <GradientStop Color="Red" Offset="0" />
                    <GradientStop Color="Blue"
                           Offset="0.25"/>
                    <GradientStop Color="Orange"
                        Offset="0.75"/>
                    <GradientStop Color="Yellow" Offset="1"/>
                  </GradientStopCollection>
                </RadialGradientBrush.GradientStops>
              </RadialGradientBrush>
         </Ellipse.Fill>

     </Ellipse>
...

You can see the results in Figure 5.

Okay, so it looks nice. But as an interface it's not particularly useful. Let's make it do something.



 
 
>>> More Using VS Articles          >>> More By Nick Chase
 



DevSource video
Devsource Video Series
Manipulating Society through Technology
Jeremy Bailenson, Director of the Virtual Human Interaction Lab at Stanford University, talks about virtual reality, avatars, Moore's law, how real world behaviors influence online reality, and societal manipulation through technology!
>> Play video
>> Read article
>> See all videos
DevLife Blog

Julia explores the Robotics Studio! (It's for more than you think.)

MSDev Blog

Messages for Bill Gates!

Make it Work
.NET makes runtime type checking a breeze. See what Peter has to say about it in this week's tips!
News
Microsoft Counts on App Support for Vista
Microsoft has taken pains to demonstrate that Windows Vista will have ample application support.
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.