My First XAML Application

 

Figure 1 - First XAML App

 

Introduction

I finally got to playing around with XAML.  I think Microsoft is on the right track here, but they have a way to go.  The visual designer is lacking many of the features of the current .NET.  There are missing properties in controls, inability to double click on buttons to insert events and other missing features. Also many of the property names changed in controls going from Window Controls in .NET 2.0 to XAML controls in .NET 3.0, so there is definitely a learning curve getting up to speed in XAML.  I suspect with the release of "Orcas", many of these inadequacies will be remedied.  In the meantime, hold on to your hats, its going to be a bumpy ride!

Installing XAML in Visual Studio 2005

In order to use XAML, in addition to Visual Studio 2005,  you need to install the .NET Framework 3.0 redistributable  and the Visual Studio 2005 extensions for .NET 3.0 (WPF and WCF).  Once you have these installed, you are off and running.  You do not need to have VISTA to run .NET 3.0 apps.  .NET 3.0 will run on XP with SP2.  VISTA just has the added advantage of already having the .NET 3.0 framework installed.

XAML Paradigm

XAML(Extensibility Application Markup Language) allows you to code your controls up in a well formed XML document. (Kinda reminds me of the old rc files in VC++, except with XML tags).  Not only can you define properties of your controls in attributes, but you can hookup events into the controls as well using  attributes.  Below is the XAML text representation for an about box button:

<Button Click="btnAbout_Click" Name="btnAbout" Foreground="#FF0000FF" ToolTip="About Box">About</Button>

The nice thing about XAML is that it is fairly clear from the tags that the element is a button and the attributes Name, Foreground, and ToolTip are easily defined with strings.  The Click event is wired to C# using an attribute (note:  you still have the option to wire the Click event using the +=  operator.)

If you want to add an Image to your button, you can embed an child image tag inside your button:

Xaml Windows Project Structure

When you create a new .NET 3.0 Windows Application, the project consists of four files and about a dozen .NET references.

The files are:

App.xaml
App.xaml.cs
Window1.xaml
Window1.xaml.cs

The references include the following .NET 3.0 Assembly references:

System
System.Data
System.Xml
WindowsBase
PresentationCore
PresentationFramework
UIAutomationProvider
UIAutomationTypes
ReachFramework
System.Printing
System.ServiceModel
System.Runtime.Serialization
System.IdentityModel
 

App.xaml is the xaml application file containing the following markup structure

Listing 1 - Application XAML definition

<Application x:Class="WindowsApplication1.App"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    StartupUri="Window1.xaml">
    <
Application.Resources>        

    </Application.Resources>
</
Application>

This structure defines the name of the application class as well as the starting window for this application (Window1.xaml).  Note that everything that was done in code and C# attributes for the Windows application in .NET 2.0 are now done in XML.

Any code that needs to execute is done inside a code-behind partial class under App.xaml.cs.  For example, if you wanted to read a database as soon as the app started up, you could do this in the Activation event of the application:

Listing 2  - App.xml to wire up Activation event to event handler App_Activated:

<Application x:Class="WindowsApplication1.App"
   
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   
StartupUri="Window1.xaml" Activated="App_Activated">
    <
Application.Resources>
    </
Application.Resources>
</
Application>

Listing 3  - App.xml.cs  code-behind:

using System;
using
System.Windows;
using
System.Data;
using
System.Xml;
using
System.Configuration

namespace WindowsApplication1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>

    public partial class App : System.Windows.Application
    {
        void App_Activated(object sender, EventArgs e)
        {
            MessageBox.Show("Read Database.");
        }

    }
}

The XAML Window uses the exact same paradigm.  Windows controls are contained within the nested tags of the XAML window file.  You can put as many controls in here as you want.  The designer gives you the ability to drag and drop controls onto a XAML Window and also edit the controls in a XAML text file.  In my application I dragged an InkCanvas, a Button, and a Toolbar.  The Toolbar resides inside a ToolbarTray control. All the controls are inside a Grid control.  The ToolBarTray and Grid control serve as containers for the child controls they hold.

The Button

I wanted my button to act as a way to clear out my InkCanvas, so I can remove the ugly picture I had drawn in the window and attempt to draw a better ugly picture.  I had a little trouble at first with my XAML Button on my form.  After incessantly clicking the button in the designer and realizing that the event handler code was never going to show up, I went ahead and hooked up the code by hand.  I think Microsoft is planning to fix this in "Orcas".  To hook up the button, you can either put the event handler wiring in XAML and declare the method in your code as shown in the listing below:

Listing 4 - Wiring a Button to a Button Event Handler in XAML

<Button Click="OnClearButton" Margin="100,0,117,2" Name="button1" Height="23" VerticalAlignment="Bottom">Clear</Button>

    void OnClearButton(object sender, RoutedEventArgs e)
        {
            inkCanvas1.Strokes.Clear();
        }

 Or you can wire it the old way using += inside your code behind.

Listing 5 - Wiring a Button to a Button Event Handler in code behind

        public Window1()
        {
            InitializeComponent();
            button1.Click += new RoutedEventHandler(OnClearButton);
        }

    void OnClearButton(object sender, RoutedEventArgs e)
        {
            inkCanvas1.Strokes.Clear();
        }

 

The Toolbar

Adding the ToolBar is a bit more complicated.  You need to first add a ToolbarTray to the designer.  Then you add the ToolBar inside the ToolBarTray.  To add buttons to the ToolBar, you have to add them manually, because the Items collection inside the toolbar doesn't seem to work properly in the designer (again we look forward to "Orcas").  Listing 6 shows the XAML for the toolbar in our sample application.  Note that the XAML ToolBar uses the same Button tag as a regular Windows Button.

Listing 6 -  XAML Toolbar

<ToolBarTray Height="18" Margin="21,1,24,0" Name="toolBarTray1" VerticalAlignment="Top" >
        <
ToolBar Band="1" BandIndex="1">
          <
Button IsEnabled ="True">
          </
Button>
          <
Button Click="btnAbout_Click" Name="btnAbout" Foreground="#FF0000FF" ToolTip="About Box">
            <
Image Source="about.bmp"></Image>
          </
Button>
          <
Separator/>
          <
Button ToolTip="new file" Name="btnNew">new</Button>
         <
Separator/>
          <
Button>
          </
Button>
          <
Button Name="btnOpen">open</Button>
        </
ToolBar>
</
ToolBarTray>

Also note that in order to create an Image Button, we simply add an Image node as a child node to our button node.  The Source attribute tells the button the name of the file in which to get its image.

Conclusion

XAML allows us to express a lot of the visual part of our application in XML.  XML is much easier to manipulate than code when it comes to static presentation information.  The XAML architecture also allows us to hook our code directly into the XML itself using event tags and code-behind.  Hopefully we will see some improvements in the designer in the near future so that it is at least on par with the current Visual Studio 2005 performance.  Either way, XAML is the future, so jump in and get your feet wet now with this hot new technology.