Saturday, January 20, 2007

XAML Overview

XAML is a Declarative Language with Flow Control Support

XAML is simplified creating UI for .NET Framework 3.0 programming model. With XAML we can create visible UI elements in the declarative XAML markup. Each UI will consists of at least one xml element and its zero or more attributes. It separate the UI definition from the run-time logic by using code-behind files, joined to the markup through partial class definition. An XML based declartive language is very intuitive for creating interfaces ranging from prototype to production, especially for people with a background in web design and technologies.

Unlike most other markup languages, XAML directly represents the instantiation of managed objects. This general principle enables simplified code and debugging access for objects that are crated in XAML

XAML files are XML files having .xaml file extension.


Markup Extensions

When properties take a reference type value, these properties will often require property element syntax( which always creates a new instance), or an object reference through a markup extension. A markup extension usage can potentially return an existing instance, and thus can be more versaltile or might incur less object overhead. Markup extensions are a XAML concept. In attribute syntax, curly braces({ and }) indicate a markup extension usage. This usage directs the XAML loader to escape from the general treatment of attribute values as either a literal string or directly string-convertible value. The attribute value should instead be provided by the logic with the backing class for the relevant markup extension. The most commonly used markup extensons for application programming are Binding Markup Extension, used for data binding expressions, and the resource references StaticResource Markup Extension and DynamicResource Markup Extension. By using markup extensions, you can use attribute syntax to provide reference values for properties even if that property does not support an attribute syntax for direct object instantiation.

For instance, the following example sets the value of Style property using attribute syntax. The Style property takes an instance of the Style class, a by-reference type that by default could not be specified within an attrbiute syntax string. But in this case, the attribute references a particular markup extension, StaticResource. When that markup extension is prcessed, it returns a reference to a style that was previously instantiated as a keyed resource in a resource dictionary.

...

....

Resources are just one markup extension usage enabled by either WPF or XAML. For a reference listing of markup extension, see WPF Namespace XAML Extensions or XAML Namespace (x:) Language Features. For more information about markup extensions, see Markup Extensions and XAML.

Typeconverter-Enabled Attribute Values

In the Attribute Syntax section, it was stated that the attribute value must be able to be set by a string. The basic, native handling of how strings are converted into other object tyeps or primitive vlaues is based on the String type itself. At the code level, this processing is accomplished by specifying a CLR type converter that processes the string attribute value. The Thickness structure type, commonly used to indicate measurements of a rectangular area such as a Margin, is an example of a type that has a special typeconverter-enabled attribute syntax exposed for all properties that take that type, to provide ease of use in XAML markup. The following example uses a typeconverter-enabled attribute syntax to provide a value for a Margin:

Again, whether to use the typeconverter-enabled syntax or a more verbose equivalent syntax is a coding style choice, but the typeconverter-enabled syntax promotes more streamlined markup.

For more information on how typeconverter-enabled attribute syntax is supported, see TypeConverters and XAML.

Collection Types and XAML Collection Properties

XAML specifies a language feature whereby the object element that represents a collection type can be deliberately omitted for markup. When a XAML loader processes a property that takes a collection type, an instance of the appropriate collection type is created implicitly, even if the object element for that collection is not present in the markup. In the SDK reference pages for collection types, this syntax with the deliberate omission of the object element for a collection is occasionally noted in the XAML syntax sections as Implicit Collection Syntax.

Implicit collection syntax is available for types that implement IList or IDictionary, or for arrays.

You have already seen an example of an implicit collection syntax without it being called out, in the XAML resources example:



...



...


With the exception of the root element, every object element on a page that is nested as a child element of another element is really an element that is one or both of the following cases: a member of an implicit collection property of its parent element, or an element that specifies the value of the XAML content property for the parent element (XAML content properties will be discussed in an upcoming section). In other words, the relationship of parent elements and child elements in a markup page is really a single object at the root, and every object element beneath the root is either a single instance that provides a property value, or one of the items within a collection. In the case of the resources example, the Resources property takes an object of type ResourceDictionary. The following example is equivalent syntax with the object element for the ResourceDictionary specified explicitly.




...




...



The Resources collection is an example of a collection property that is present on all WPF framework-level elements. Setting this property in XAML requires the property element syntax. Each enclosed object element within the property element becomes an item of the collection (an IDictionary implementation). Although the collection type itself typically does have a property or indexer that contains the items, that property cannot be specified in markup; it is entirely implied. For the ResourceDictionary, that property is the Item indexer.
For a more complete resource dictionary usage example, see How to: Define and Reference a Resource.

XAML Content Properties

XAML Content Properties

XAML specifies a language feature whereby any class that can be used as a XAML object element can designate exactly one of its properties to be the XAML content property for instances of the class. When a XAML loader processes an object element that has a XAML content property, any XML child elements of that object element are processed as if they were contained within an implicit property element tag representing that content property. Within your markup, property element syntax for the XAML content property can be omitted. Any child elements you specify in markup will become the value of the XAML content property.
You have already seen an example of a XAML content property without it being called out: the very first example in this topic.





Inner Text and XAML Content Properties
The StackPanel / Button example has still another variation.
XAML
Copy Code


Notice the change in how the display text for the Button is specified. The Content property was specified in attribute syntax before; this time the display string is the inner text within a Button object element. This syntax works because Content is the XAML content property of the Button base class ContentControl. The string within the element is evaluated based on the property type of the Content property, which is Object. Object does not attempt any string type conversion, therefore the value of the Content property becomes the literal string value. Alternatively, the content within the Button could have been any single Object. Controls such as Button generally define the XAML content property for the class such that the XAML content property can be used for UI and display text, for control compositing, or both.
The ability to place strings within the element as content to produce markup that resembles other common markup languages is particularly important for the flow document model (for details, see Documents in Windows Presentation Foundation) and for localization (see Globalization for the Windows Presentation Foundation).


XAML Content Property Values Must Be Contiguous

The value of a XAML content property must be given either entirely before or entirely after any other property elements on that object element. This is true whether the value of a XAML content property is specified as a string, or as one or more objects. For instance, the following markup does not compile:

This is illegal essentially because if this syntax were explicit by using property element syntax for the content property, then the content property would be set twice:

A similarly illegal example is if the content property is a collection, and child elements are interspersed with property elements:








Content Models

A class might support a usage as a XAML element in terms of the syntax, but that element will only function properly in an application or page when it is placed in an expected position of an overall content model or element tree. For example, a MenuItem should typically only be placed as a child of a MenuBase derived class such as Menu. Content models for specific elements are documented as part of the remarks on the class pages for controls and other WPF classes that can be used as XAML elements. For some controls that have more complex content models, the content model is documented as a separate conceptual topic. See Content Models.


Case and Whitespace in XAML

XAML is case sensitive. Object elements, property elements, and attribute names must all be specified by using the proper casing when compared by name to the underlying type in the assembly, or to a member of a type. The values for attributes are not always case sensitive. Case sensitivity for values will depend on the type converter behavior associated with the property that takes the value, or the property value type. For instance, properties that take the Boolean type can take either true or True as equivalent values, but only because the default string type conversion for Boolean already permits these as equivalents.

XAML loaders and serializers will ignore or drop all nonsignificant whitespace, and will normalize any significant whitespace. This behavior is generally only of consequence when you specify strings within XAML content properties. In simplest terms, XAML converts space, linefeed and tab characters into spaces, and then preserves one space if found at either end of a contiguous string. The full explanation of XAML whitespace handling is not covered in this topic. For details, see Whitespace Processing in XAML.

More about XAML Syntax

Implicit collection syntax and XAML content properties are both features of the XAML language that enable omission of certain inferred tags. The goal of these features is to make the parent-child relationships of elements on a page more apparent when authoring or examining the markup.
For more information about attribute syntax and property element syntax, as well as other terms that are used when describing XAML syntax throughout the SDK documentation, see XAML Syntax Terminology.

More about XAML Syntax

Implicit collection syntax and XAML content properties are both features of the XAML language that enable omission of certain inferred tags. The goal of these features is to make the parent-child relationships of elements on a page more apparent when authoring or examining the markup.
For more information about attribute syntax and property element syntax, as well as other terms that are used when describing XAML syntax throughout the SDK documentation, see XAML Syntax Terminology.

XAML Root Elements and xmlns

XAML files must have only one root element, in order to be a both well-formed XML file and a valid XAML file. Typically you should choose an element that is part of the application model (for example, Window or Page for a page, ResourceDictionary for an external dictionary, or Application for the application definition root). The following example shows the root element of a typical XAML file for a WPF page, with the root element Page.

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...


The root element also contains the attributes xmlns and xmlns:x. These attributes indicate to the XAML loader which namespaces contain the element definitions. The xmlns attribute specifically indicates the default xmlns namespace. Within the default xmlns namespace, object elements in the markup can be specified without a prefix. For most WPF application scenarios, and for virtually all of the examples given in the WPF sections of the SDK, the default xmlns namespace is mapped to the WPF namespace http://schemas.microsoft.com/winfx/2006/xaml/presentation. The xmlns:x attribute indicates an additional xmlns namespace, which maps the XAML language namespace http://schemas.microsoft.com/winfx/2006/xaml. Required language components defined by the XAML specification are prefixed by x: when referenced in the markup of a file with this mapping. This usage of xmlns to define a scope for usage and mapping is consistent with the XML 1.0 specification. Note that the xmlns attributes are only strictly necessary on the root element of the page or application. xmlns definitions will apply to all child elements of the root (this behavior is again consistent with the XML 1.0 specification for xmlns.) xmlns attributes are also permitted on other elements beneath the root, and would apply to any child elements of the defining element. However, this usage is not typical, because frequent definition or redefinition of xmlns namespaces can result in a markup style that is difficult to read.

The WPF assemblies are known to contain the WPF namespaces because of configuration that is part of your project build file. Assemblies are also mapped in the targets files. Therefore, mapping the xmlns is all that is necessary in order to reference XAML elements that come from WPF assemblies. For your own custom assemblies, or for assemblies outside of WPF, you can specify the assembly as part of the xmlns mapping. For more information about how xmlns namespaces and the namespaces of the backing code in assemblies are related, see XAML Namespaces and Namespace Mapping.
The x: Prefix
In the previous root element example, the prefix x: was used to map the XAML namespace http://schemas.microsoft.com/winfx/2006/xaml. This x: prefix will be used to map the XAML namespace in the templates for projects, in examples, and in documentation throughout this SDK. The x: prefix/XAML namespace contain several programming constructs that you will use quite frequently in your XAML. The following is a listing of the most common x: prefix/XAML namespace programming constructs you will use:
x:Type: Constructs a Type reference based on a type name. This is used to specify attributes that take Type, such as System.Windows.Style.TargetType.
x:Key: Sets a unique key for resources in a ResourceDictionary.
x:Class: Specifies the CLR namespace and class name for the class that provides code-behind for a XAML page.
x:Static: Enables a value reference to a static value that is not otherwise a XAML settable property.
There are also more programming constructs in the x: prefix/XAML namespace, which are not as common. For details, see XAML Namespace (x:) Language Features.

Events and XAML Code-Behind
Most WPF applications consist of both markup and code-behind. Within a project, the XAML is written as a .xaml file. and a CLR language such as Microsoft Visual Basic .NET or C# is used to write a code-behind file. When a XAML file is compiled, the location of the XAML code-behind file for each XAML page is identified by specifying a namespace and class as the x:Class attribute of the root element of the XAML page.
In the examples so far, you have seen several buttons, but none of these buttons had any logical behavior associated with them yet. The primary application-level mechanism for adding a behavior for an object element is to use an existing event of the element class, and to write a specific handler for that event that is invoked when that event is raised at runtime. The event name and the name of the handler to use are specified in the markup, whereas the code that implements your handler is defined in the code-behind.
XAML
Copy Codexmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyNamespace.MyPageCode">


C#
Copy Codenamespace MyNamespace
{
public partial class MyPageCode
{
void ClickHandler(object sender, RoutedEventArgs e)
{
Button b = e.Source as Button;
b.Background = Brushes.Red;
}
}
}
Notice that the code-behind file uses the namespace MyNamespace and declares MyPageCode as a partial class within that namespace. This parallels the x:Class attribute value of MyNamespace.MyPageCode that was provided in the markup root. The compiler will automatically create a partial class for any compiled XAML page, by deriving a class from the root element type. When you provide code-behind that also defines the same partial class, the resulting code is combined within the same namespace and class of the compiled application.
For more information about requirements for code-behind programming, see the Code-behind, Event Handler, and Partial Class Requirements section of Code-Behind and XAML.
If you do not want to create a separate code-behind file, you can also inline your code within a XAML file. However, inline code is a less versatile technique that has quite a few limitations. For details, see Code-Behind and XAML.

Event Attribute Syntax
When you specify behaviors through events in markup, you typically use attribute syntax to attach handlers. The object element where the event attribute is specified becomes the instance that listens for the event and calls the handler. The name of the specific event you want to handle is the attribute name. The attribute value is the method name of the handler you will define. You must then provide the handler implementation of the delegate for that event in code-behind, in a language such as Microsoft Visual Basic .NET or C#.
Each WPF event will report event data when the event is raised. Event handlers can use this event data. In the preceding example, the handler obtains the reported event source through the event data, and then sets properties on that source.

Routed Events

A particular event feature that is unique to WPF is a routed event. Routed events enable an element to handle an event that was raised by a different element. When specifying event handling with a XAML attribute, the routed event can be listened for and handled on any element, including elements that do not list that particular event in the class members table. This is accomplished by qualifying the event name attribute with the owning class name. For instance, the parent StackPanel in the ongoing StackPanel / Button example could register a handler for the child element button's Click event by specifying the attribute Button.Click on the StackPanel object element, with your handler name as the attribute value. For more information, see Routed Events Overview.

x:Name

By default, the object instance that is created by processing an object element does not possess a unique identifier or an inherent object reference that you can use in your code. If you call a constructor in code, you almost always use the constructor result to set a variable to the constructed instance, so that you can reference the instance later in your code. In order to provide easy access to objects that were created through a markup definition, XAML defines the x:Name attribute . You can set the value of the x:Name attribute on any object element. In your code-behind, the identifier you choose is equivalent to an instance variable that refers to the constructed instance. In all respects, named elements function as if they were object instances, and your code-behind can reference the named elements to handle run-time interactions within the application.

WPF framework-level XAML elements inherit a Name property, which is equivalent to the XAML defined x:Name attribute. Certain other classes also provide property-level equivalents for x:Name. Generally, if you cannot find a Name property, use x:Name instead.
The following example sets Name on a StackPanel element. Then, a handler on a Button within that StackPanel references the StackPanel through its instance reference buttonContainer as set by Name.


...


C#

void RemoveThis(object sender, RoutedEventArgs e)
{
FrameworkElement fe = e.Source as FrameworkElement;
if (buttonContainer.Children.Contains(fe))
{
buttonContainer.Children.Remove(fe);
}
}
Just like a variable, the name for an instance is governed by a concept of scope, so that names can be enforced to be unique. The primary markup that defines a page denotes one unique namescope. However, other markup sources can interact with a page at runtime, such as styles, or templates within styles. For more information on x:Name and namescopes, see Name, x:Name Attribute, or WPF Namescopes.

Attached Properties and Attached Events

XAML specifies a language feature that enables certain properties or events to be specified on any element, regardless of whether the property or element exists in the members table for the element it is being set on. The properties version of this feature is called an attached property, the events version is called an attached event. Conceptually, you can think of attached properties and attached events as global members that can be set on any element/class.
Attached properties in XAML are typically used through attribute syntax. In attribute syntax, you specify an attached property in the form ownerType.propertyName. Superficially, this resembles a property element usage, but in this case the ownerType you specify is always a different type than the object element where the attached property is being set. ownerType is the type that provides the accessor methods that are required by a loader in order to get or set the attached property value. The most common scenario for attached properties is to enable child elements to report a property value to their parent element.
The following example illustrates the DockPanel.Dock attached property. The DockPanel class defines the accessors for DockPanel.Dock and therefore owns the attached property. The DockPanel class also includes logic that iterates its child elements and specifically checks each element for a set value of DockPanel.Dock. If a value is found, that value is used during layout to position the child elements. Use of the DockPanel.Dock attached property and this positioning capability is in fact the motivating scenario for the DockPanel class.





In Windows Presentation Foundation (WPF), all attached properties are also implemented as dependency properties. For details, see Attached Properties Overview.
Attached events use a similar ownerType.eventName form of attribute syntax. Just like the non-attached events, the attribute value for an attached event in XAML specifies the name of the handler method that is invoked when the event is handled on the element.

One scenario where attached events are used is for device input events that can be handled on any element, such as mouse buttons. An example of such an attached event is Mouse.MouseDown. However, most WPF framework-level elements can use this event without the attached event usage. This is because the base element class UIElement creates an alias for the Mouse.MouseDown attached event and exposes that alias in the UIElement members table (as MouseDown). As a result, you usually do not need to specify attached event syntax in page or application programming, unless you are using custom elements, or object elements that do not derive from UIElement but still have a visual representation (these are rare). In WPF, all attached events are also implemented as routed events. ContentElement also exposes aliases for the input events, for use by the flow document model. For details, see Routed Events Overview.
Anatomy of a XAML Page Root Element
The following table shows a typical XAML page root element broken down, showing the specific attributes of a root element identified in this topic:
Opening object element of the root element
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
The default (WPF) namespace
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
The XAML namespace
x:Class="MyNamespace.MyPageCode"
The partial class declaration that connects markup to any code-behind defined into this same partial class
>
End of object element for the root, not closed yet because the page contains child elements

Base Classes and XAML

Underlying XAML and its schemas is a collection of classes that correspond to CLR objects as well as markup elements to be used in XAML. However, not all classes can be mapped to elements. Abstract classes, such as ButtonBase, and certain nonabstract base classes, are used for inheritance in the CLR objects model and do not have corresponding XAML markup tags. Base classes are still important to XAML development because each of the concrete XAML elements inherits members from the base class. Often these members includes properties that can be set as attributes on the element, or events that can be handled. FrameworkElement is the concrete base UI class of WPF at the WPF framework level. When designing UI, you will use various shape, panel, decorator, or control classes, which all derive from FrameworkElement. A related base class, FrameworkContentElement, supports document-oriented elements that work well for a flow layout presentation, using APIs that deliberately mirror the APIs in FrameworkElement. The combination of attributes at the element level and a CLR object model provides you with a set of common properties that are settable on the majority of concrete XAML elements, regardless of the exact element type and its underlying class.

XAML Security

XAML is a markup language that directly represents object instantiation and execution. Therefore, elements created in XAML have the same ability to interact with system resources (network access, file system IO, for instance) as the equivalent generated code does.
WPF supports the .NET security framework Code Access Security (CAS). This means that WPF content running in the internet zone has reduced execution permissions. "Loose XAML" (pages of noncompiled XAML interpreted at load time by a XAML viewer) and XAML browser application (XBAP) are usually run in this internet zone and use the same permission set. However, XAML loaded in to a fully trusted application has the same access to the system resources as the hosting application does. For more information, see Windows Presentation Foundation Partial Trust Security.