Child Elements and Keywords in XAML
A XAML file, like all XML files, must have a single root object element. Therefore, it should come as no surprise that object elements can support children that are more than just the property elements introduced in the preceding chapter. Property elements aren’t true children as far as XAML is concerned.
This chapter examines the types of children that object elements can have. It also summarizes all the keywords in the XAML language namespace, although many of them are discussed in depth in the two chapters that follow.
Children of Object Elements
An object element can have three types of children:
- A value for a content property
- Collection items
- A value that can be type-converted to the object element
We’ll look at the first two types of children now, but save the third type for Chapter 4, “Extending XAML.”
The Content Property
Most classes designate a property (via a custom attribute) that should be set to whatever content is inside the XML element. This property is called the content property, and it is really just a convenient shortcut to make the XAML representation more compact.
Button’s Content property is (appropriately) given this special designation, so the following Button:
<
Button
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
"Content
=
"OK
"/>
could be rewritten as follows:
<
Button
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
">
OK</
Button
>
Or, more usefully, this Button with more complex content:
<
Button
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
">
<
Button.Content
>
<
Rectangle
Height
=
"40
"Width
=
"40
"Fill
=
"Black
"/>
</
Button.Content
>
</
Button
>
could be rewritten as follows:
<
Button
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
">
<
Rectangle
Height
=
"40
"Width
=
"40
"Fill
=
"Black
"/>
</
Button
>
There is no requirement that the content property must actually be called Content; classes such as ComboBox and ListBox use their Items property as the content property. For example, this ListBox:
<
ListBox
Width
="100">
<
ListBox.Items
>
<
ListBoxItem
>
1</
ListBoxItem
>
<
ListBoxItem
>
2</
ListBoxItem
>
<
ListBoxItem
>
3</
ListBoxItem
>
</
ListBox.Items
>
</
ListBox
>
is equivalent to the following ListBox:
<
ListBox
Width
=
"100
">
<
ListBoxItem
>
1</
ListBoxItem
>
<
ListBoxItem
>
2</
ListBoxItem
>
<
ListBoxItem
>
3</
ListBoxItem
>
</
ListBox
>
Both produce the result in Figure 2.1.
FIGURE 2.1 A simple ListBox has three children in its Items collection.
Collection Items
XAML enables you to add items to the two main types of collections that support indexing: lists and dictionaries.
Lists
A list is any collection that implements System.Collections.IList, such as System.Collections.ArrayList or numerous collection classes defined by various frameworks. For example, the following XAML adds two items to a ListBox control whose Items property is an ItemCollection that implements IList:
<
ListBox
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
">
<
ListBox.Items
>
<
ListBoxItem
Content
=
"Item 1
"/>
<
ListBoxItem
Content
=
"Item 2
"/>
</
ListBox.Items
>
</
ListBox
>
This is equivalent to the following code:
C# (WPF and Silverlight):
System.Windows.Controls.ListBox
listbox =new
System.Windows.Controls.ListBox
(); System.Windows.Controls.ListBoxItem
item1 =new
System.Windows.Controls.ListBoxItem
(); System.Windows.Controls.ListBoxItem
item2 =new
System.Windows.Controls.ListBoxItem
(); item1.Content ="Item 1
"; item2.Content ="Item 2
";listbox.Items.Add(item1);
listbox.Items.Add(item2);
C# (Windows Store and Universal Apps):
Windows.UI.Xaml.Controls.ListBox
listbox =new
Windows.UI.Xaml.Controls.ListBox
(); Windows.UI.Xaml.Controls.ListBoxItem
item1 =new
Windows.UI.Xaml.Controls.ListBoxItem
(); Windows.UI.Xaml.Controls.ListBoxItem
item2 =new
Windows.UI.Xaml.Controls.ListBoxItem
(); item1.Content ="Item 1
"; item2.Content ="Item 2
";listbox.Items.Add(item1);
listbox.Items.Add(item2);
Furthermore, because Items is the content property for ListBox, you can shorten the XAML even further, as follows:
<
ListBox
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
">
<
ListBoxItem
Content
=
"Item 1
"/>
<
ListBoxItem
Conten
t=
"Item 2
"/>
</
ListBox
>
In all these cases, the code works because ListBox’s Items property is automatically initialized to any empty collection object. If a collection property is initially null instead (and is read/write, unlike ListBox’s read-only Items property), you need to wrap the items in an explicit element that instantiates the collection. ListBox does not act this way, so an imaginary OtherListBox element demonstrates what this could look like:
<
OtherListBox
>
<
OtherListBox.Items
>
<
ItemCollection
>
<
ListBoxItem
Content
=
"Item 1
"/>
<
ListBoxItem
Content
=
"Item 2
"/>
</
ItemCollection
>
</
OtherListBox.Items
>
</
OtherListBox
>
Dictionaries
ResourceDictionary is a commonly used collection type in all XAML-based frameworks that you’ll see more of in Chapter 16, “Resources.” It implements System.Collections.IDictionary, so it supports adding, removing, and enumerating key/value pairs in procedural code, as you would do with a typical hash table. In XAML, you can add key/value pairs to any collection that implements IDictionary. For example, the following XAML adds two Colors to a ResourceDictionary:
<
ResourceDictionary
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation
"xmlns:x
=
"http://schemas.microsoft.com/winfx/2006/xaml
">
<
Color
x:Key
=
"1
">
White</
Color
>
<
Color
x:Key
=
"2
">
Black</
Color
>
</
ResourceDictionary
>
This leverages the XAML Key keyword (defined in the secondary XML namespace), which is processed specially and enables us to attach a key to each Color value. (The Color type does not define a Key property.) Therefore, the XAML is equivalent to the following code:
C# (WPF and Silverlight):
System.Windows.ResourceDictionary
d =new
System.Windows.ResourceDictionary
(); System.Windows.Media.Color
color1 = System.Windows.Media.Colors
.White; System.Windows.Media.Color
color2 = System.Windows.Media.Colors
.Black;d.Add(
"1
", color1);d.Add(
"2
", color2);
C# (Windows Store and Universal Apps):
Windows.UI.Xaml.ResourceDictionary
d =new
Windows.UI.Xaml.ResourceDictionary
(); Windows.UI.Color
color1 = Windows.UI.Colors
.White; Windows.UI.Color
color2 = Windows.UI.Colors
.Black;d.Add(
"1
", color1);d.Add(
"2
", color2);