How XAML works
Tuesday, 17 November 2009
Article Index
How XAML works
Properties

XAML can be confusing - especially if you think it is a markup language like HTML - it isn't.

 

Banner

XAML can be confusing - especially if you think it is a markup language like HTML - it isn't.

XAML is a, mostly declarative, object instantiation language – that is it’s a way of describing using XML what objects should be created and how they should be initialised before your program starts running. If you keep this in mind then XAML is becomes a lot more transparent and easier to understand.

 

Its use in conjunction with WPF is just one of its many possible applications and indeed it has started to appear in other places – Windows Workflow for example. To explain exactly what XAML is this article works with custom classes that have nothing to do with WPF so that we can find out about XAML in a completely general context.

Declaritive instantiation

We could start with a non-WPF project to prove how general XAML is we but this would waste a lot of time adding references and “usings”. So let’s start with a simple WPF Application. You don’t need to modify any of the generated code but you do need to add a simple custom class with which to try out XAML:

public class MyClass
{
public MyClass()
{
}
}

All that is necessary for a class to be instantiable by XAML is that it has a parameterless constructor and it can’t be a nested class. It can have other constructors but these play no part in its working with XAML. Notice that as structs have a default parameterless constructor provided automatically by the system you can instantiate structs in XAML.

Now that we have our minimal class we can write some XAML to create an instance of it. However first there has to be some way of making the link between the XAML document and the class definition. This is achieved by importing the class’s namespace into XAML.

You can import the namespace of any assembly and use namespaces to indicate exactly which class you are referring to. In this case we need to import the namespace of the assembly that the XAML file is part of, i.e. the current project. So moving to the XAML editor we need to add a single line to the <Window> tag:

 

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/
winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
xmlns:m="clr-namespace:WpfApplication1"
Title="Window1" Height="300"
Width="300" Loaded="Window_Loaded">

The “clr-namespace” is a special token which is interpreted to mean “get the namespace from the named CLR runtime”. In general you might also need an “assembly=” token to supply the location of the assembly but in this case it’s assumed to be the current project.

Following this any name prefixed by m: is taken from the namespace of the current project.

The next thing we have to do is to get rid of the <Grid> tags as we cannot nest a general class within a grid – it needs a class that can be displayed. To create the instance of our class all we have to enter is:

 <m:MyClass>
</m:MyClass>
</Window>

The project should now run without errors. If you do see any errors then it will be due to loss of synchronisation between namespaces – simply run the project again. The need to keep namespaces and other generated files in sync is one of the problems of splitting instantiation from the runtime.

Naming objects

So we have a working program that creates an instance of MyClass but this does us very little good as the instance is dynamic and goes out of scope as soon as the main form is loaded!

To keep the instance in scope, and to allow us to work with it within the C# code, we need to give the instance a name. Standard WPF components are generally given a name via the NAME property but a more direct mechanism for custom classes is to use the facilities provided by the XAML “x” namespace. The “x:Name” attribute can be used to set the name used by XAML to create the instance:

<m:MyClass x:Name="MyObject1">
</m:MyClass>

With this change you can now run the program and, with the help of a breakpoint and the debugger, you can confirm that there it really does create MyObject1.

If you would like to see the generated C# code that does the instantiation then load the file called Window1.g.cs - click on the Show All files icon in the Solution Explorer and its in the obj\Debug directory - where you will discover that what happens boils down to:

internal WpfApplication1.
MyClass MyObject1;

followed a few lines later by:

this.MyObject1 = ((WpfApplication1.
MyClass)(target));

Not exactly the way most of us would do it, but it serves a higher purpose!

As already mentioned, WPF classes inherit a Name property which can be used in place of x:Name. If a class doesn’t have a Name property then use x:Name, if it does use it, but don’t give your class a Name property unless it sets the name of the new object.

To assign a name property to a class you simply use the RuntimeNameProperty Attribute to designate a property that will store the name of the instance. For example:

[RuntimeNameProperty("MyName")]
public class MyClass
{
public MyClass(){}
 public string MyName
{
get { return _MyName; }
set { _MyName= value; }
}
private string _MyName= string.Empty;

}

However this only works if the class belongs to another assembly and not the one actively being edited in Visual Studio say. Notice also that the XAML compiler will create an instance with the name you specify and store the name in the property in case you need to make use of it.

<ASIN:0735619573>

<ASIN:0672330318>

<ASIN:0596526733>



Last Updated ( Friday, 19 March 2010 )
 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.