You can set properties on objects that you declared by using object element syntax. There are multiple ways to set properties in XAML:
By using attribute syntax.
By using property element syntax.
By using content element syntax.
By using a collection syntax (which is usually implicit collection syntax).
As with object declaration, this list of techniques does not imply that a given property could be set with any of the techniques. Some properties support only one of the techniques. Some properties might support combinations; for example, a property that supports content element syntax might also support property element syntax or attribute syntax. This depends both on the property and on the object type that the property uses. The possibilities for XAML syntax are provided in the "XAML Usage" sections of reference pages for each property that can be set in XAML. There are also Silverlight properties that cannot be set in XAML by any means, and must instead be set using code.
A read-only property cannot be set by any means, either in XAML or in code, unless there is an additional mechanism in play. This might be calling a constructor overload that sets to the property's internal representation, a method that is not strictly the property accessor, or a property relationship such as a calculated property that relies on the values of other settable properties plus perhaps a service or behavior influence on that property value. Also, collections give an appearance that you are setting a read-only property, but in fact you are not (see Setting a Property by Using a Collection Syntax).
Setting a Property by Using Attribute Syntax
Use the following syntax, where objectName is the object you want to instantiate, propertyName is the name of the property that you want to set on that object, and propertyValue is the value to set.
<objectName propertyName="propertyValue" .../>
-or-
<objectName propertyName="propertyValue">
...<!--element children -->
</objectName>
Either of these syntaxes enable you to declare an object and set a property on that object. Although the first example is a single element in markup, there are actually discrete steps here with regard to how a XAML processor parses this markup. First, the presence of the object element indicates that a new objectName object must be instantiated. Only after such an instance exists can the instance property propertyName can be set on it.
The following example uses attribute syntax for three attributes to set the width, height, and fill properties of a Rectangle object.
<Rectangle Width="100" Height="100" Fill="Blue" />
Setting a Property by Using Property Element Syntax
Some properties can be set by using property element syntax. To use property element syntax, it must be possible to specify a new instance of an object element in order to "fill" the property element value.
To use property element syntax, you create XML elements for the property that you want to set. These elements are in the form <object.property>. In standard XML, this element would just be considered an element that has a dot in its name. However, in XAML, the dot in the element name identifies the element as a property element, with property being a property of object.
In the following grammar, property is the name of the property that you want to set and propertyValueAsObjectElement is a new object element that declares a new object, which is of the value type that the property expects.
<object>
<object.property>
propertyValueAsObjectElement
</object.property>
</object>
The following example uses property element syntax to set the fill of a Rectangle with a SolidColorBrush object element. (Within the SolidColorBrush, the Color is set by using attribute syntax.) The rendered result of this XAML is identical to the previous XAML example that set Fill using attribute syntax.
<Rectangle
Width="100"
Height="100"
>
<Rectangle.Fill>
<SolidColorBrush Color="Blue"/>
</Rectangle.Fill>
</Rectangle>
Setting a Property by Using Content Element Syntax
Some Silverlight objects define a property that enables a XAML syntax whereby you can omit the property name and set the property by providing a value within the owning type's object element tags. This is known as content element syntax. If content element syntax is available, the syntax will be shown in the XAML Usage sections of Syntax for the property in the Silverlight reference documentation. For example, the Text property page for TextBlock shows an alternative XAML syntax that uses content element syntax instead of attribute syntax to set the string value of Text.
The following example sets the Text property of a TextBlock without explicitly specifying the Text property. In this case the property is set using what XML would consider to be content or "inner text," rather than using an attribute, or declaring an object element.
<TextBlock>
Hello!
</TextBlock>
Note: |
|---|
Another way to identify which objects support a content property syntax and which property implements it is available through examining the CLR attributes that are applied to the type. This can be done by reflection. Any type that supports content element syntax will have ContentPropertyAttribute applied. |
Setting a Property by Using a Collection Syntax
Collections are an interesting case in XAML, because there are several variations of collection syntax. Also, it might at first appear that XAML is letting you "set" read-only collection properties. In reality, what XAML enables here is adding items to a collection.
Something that is always omitted from the XAML collection syntaxes is the property of the collection type that holds the collection items. In many cases, such a property is defined as a CLR indexer. For collections, what is really necessary to do anything useful with a collection from XAML is not a property, but a method: the Add method. Thus, when the XAML processor encounters one or more object elements within a collection syntax, each such object is first created, then each new object is added to the collection by calling the collection's Add method.
The following example shows a collection property that uses a collection type that is constructible (you can define and initialize the actual collection as an object element in XAML).
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- Here the GradientStopCollection tag is specified. -->
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
However, generally for a Silverlight property that takes a collection, the XAML parser implicitly knows the type of the collection, based on the property the collection is contained in. Therefore, you can omit the object element for the collection itself, as shown in the following example.
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Also, there are properties that are collection properties but are also identified as the content property for the class. This is the case with the GradientStops property being used in the previous examples. Therefore, you can also omit the property element. This results in the following markup:
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush>
This combination of collection and content syntaxes is most frequently seen in the classes that are used extensively for control compositing, such as panels. For instance, the following examples show the explicit XAML and the simplest possible XAML for compositing two UI elements within a StackPanel.
<!--explicit-->
<StackPanel>
<StackPanel.Children>
<!--UIElementCollection-->
<TextBlock>Hello</TextBlock>
<TextBlock>World</TextBlock>
<!--/UIElementCollection-->
</StackPanel.Children>
</StackPanel>
<!--simple-->
<StackPanel>
<TextBlock>Hello</TextBlock>
<TextBlock>World</TextBlock>
</StackPanel>
Notice the commented-out UIElementCollection in the explicit syntax. This is commented out because even though the collection in question will exist in the created object tree, you cannot specify it explicitly in XAML, because UIElementCollection is not a constructible class. There are scenarios for deliberately and explicitly including the collection class in the markup (such as giving the collection an x:Name so that it can be referenced more easily in code). However, be careful to not explicitly declare collection classes that cannot be constructed by the XAML parser because of their class characteristics.
When to Use Attribute or Property Element Syntax to Set a Property
All properties that support being set in XAML will support attribute or property element syntax for direct value setting, but potentially will not support either syntax interchangeably. Some properties do support either syntax, and some properties support additional syntax options such as the content element syntax for Text shown previously. The type of XAML syntax supported by a property partially depends on the type of object that the property uses as its property type. If the property type is a primitive type, such as a double, integer, or string, the property always supports attribute syntax.
The following example uses attribute syntax to set the width of a Rectangle. The Width property supports attribute syntax, because the property value is a double.
<Rectangle Width="100" />
You can also use attribute syntax to set a property if the object type you use to set that property can be created by type-converting a string. For primitives, this is always the case. However, certain other object types can also be created by using a string specified as an attribute value (instead of requiring object element syntax). This technique uses an underlying type conversion, supported either by that particular property or generally by that property type. The string value of the attribute is parsed, and the string information is used to set properties that are important for the initialization of the new object. Potentially, a specific type converter can also create different subclasses of a common property type, depending on how it uniquely processes information in the string. Object types that support this behavior will have a special grammar listed in the syntax section of the documentation.
The following example uses attribute syntax to set the fill of a Rectangle. The Fill property supports an attribute syntax when you use a SolidColorBrush to set it. This is because the Brush abstract type that backs the Fill property supports a type-converted grammar that can create a SolidColorBrush that is initialized with the attribute-specified string as its Color (for details on this specific example, see Brush and SolidColorBrush).
<Rectangle Width="100" Height="100" Fill="Blue" />
You can use property element syntax to set a property if the object you use to set that property supports object element syntax. If the object supports object element syntax, the property also supports property element syntax. The following example uses property element syntax to set the fill of a Rectangle. The Fill property supports property element syntax when you use a SolidColorBrush to set it, because SolidColorBrush supports object element syntax and satisfies the property's requirements that its value is set with a type of Brush. (The SolidColorBrush also has its Color property set, using attribute syntax. The rendered result of this XAML is identical to the previous XAML example that set Fill using attribute syntax.)
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<SolidColorBrush Color="Blue"/>
</Rectangle.Fill>
</Rectangle>
Because of the Brush type converter, SolidColorBrush is the only Brush case where you can choose either property element syntax or attribute syntax for a new Fill value (without resorting to a resource reference, or binding). For the other Brush types that you can use to set the Fill, there is no type converter behavior available to create that type of Brush. Therefore, if you want to set a Fill by using a brush type such as ImageBrush, you must use the property element syntax for Fill and declare an ImageBrush as an object element to provide the property value, or use a markup extension as is documented in the next section.
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<ImageBrush ImageSource="forest.jpg"/>
</Rectangle.Fill>
</Rectangle>