Property Path Syntax

Microsoft Silverlight will reach end of support after October 2021. Learn more.

The PropertyPath object supports a string-based syntax for setting various properties that take the PropertyPath type as their value. A property path string might be set directly to an attribute in XAML. The same string syntax can be used to set the Path property for a PropertyPath that sets the equivalent property in code. There are two distinct feature areas in Silverlight that use a property path: data binding, and animation targeting. Data binding and animation targeting each evaluate the paths differently, so this topic describes property path syntax separately for each.

This topic contains the following sections.

  • PropertyPath for Objects in Data Binding
  • PropertyPath for Animation Targets
  • PropertyPath in Code
  • Related Topics

PropertyPath for Objects in Data Binding

In Silverlight, you can bind to the target value of any dependency property. The source property value for a data binding need not be a dependency property; it can be a property on a CLR object if certain conditions are met (see Data Binding). The source object can also be an existing dependency object referenced either by name or by a relative position in the object graph.

You can bind to an individual property value, or you can bind to a target property that takes lists or collections using a source and path that returns a similar collection. The data-binding engine matches the collection items of source to target, resulting in behavior such as populating a ListBox with an items list.

You can use the following syntaxes to specify a property path for data binding:

  • Single property on the immediate object as data context.

  • Multiple property (indirect property targeting).

  • Single property waiting for context through style/template.

  • Attached property.

  • Indexer.

Single Property on the Immediate Object as Data Context

<Binding Path="propertyName" .../>

propertyName must resolve to the name of a property that is in the current DataContext or is a specific dependency object source specified by ElementName or RelativeSource. If your binding updates the source (TwoWay), that property must be read/write and the source object must be mutable.

Multiple Property (Indirect Property Targeting)

<Binding Path="propertyName.propertyName2" .../>
-or-
<Binding Path="propertyName.propertyName2.propertyName3" .../>
-etc.-

propertyName must resolve to the name of a property that is in the current DataContext or is a specific dependency object source specified by ElementName or RelativeSource. The path properties propertyName and propertyName2 can be any properties that exist in a relationship, where propertyName2 is a property that exists on the type that is the value of propertyName. This syntax can extend beyond two properties: you can traverse into the object tree to return deeply nested properties, so long as every property along the path meets general criteria (all pathed properties must be public; the end property must be public and must be mutable, end property must be read/write if used for two-way binding.)

Single Property Waiting for Context Through Style/Template

<Binding Path="(ownerType.propertyName)" .../>

The parentheses indicate that this property in a PropertyPath should be constructed using a partial qualification because it needs late-binding context information, such as the type being applied to for applied templates. It can use a prefix usage for a XAML namespace to find the type. The ownerType searches types that a XAML processor has access to, based on xmlns mappings (or using the default XAML namespace if unqualified). propertyName must resolve to the name of a property that exists on the ownerType.

Attached Property

<object Path="...(ownerType.propertyName)..." .../>

The parentheses indicate that this portion in a PropertyPath should be constructed using an owner qualification rather than traversal. It can use a prefix usage for a XAML namespace to find the type. propertyName must resolve to the name of a property that exists on the ownerType. The property specified as propertyName must be a DependencyProperty. (All Silverlight attached properties are implemented as dependency properties, so this is a concern only for custom attached properties. Also, attached properties generally appear in paths only when ElementName or RelativeSource specifies the source, because using a DependencyObject for a business object data source is uncommon.)

Indexer

Indexers can be used for accessing properties in a path and obtaining items from a list, but with some notable restrictions:

  • Numeric integer indexers are supported.

  • Beginning in Silverlight 4, string indexers are supported.

  • Only one-dimensional array indexing is supported.

  • The type being indexed must implement or inherit IList. (List<T> is accepted, because it implements IList. However IList<T> is not accepted.)

Numeric integer indexes are specified by declaring the zero-based index within bracket ([]) characters after the property name; for example, Employees[2].

Property path evaluation first attempts to use integer indexing for a collection. If that indexing is not valid for the collection, then the information within [] is processed as a string. String indexing from a property path generally expects a collection / business object that is a dictionary with string keys. String indexing supports binding to dynamic data objects where the CLR structure of the data source can change, but the string keys represent a data contract that can still be bound to by a client UI.

Validation uses indexers to access items of an attached property's collection as part of its property path usage. The validation structure for the application can declare UI states within templates that are used only when validation errors are raised, and can then reference the active error objects in that context. For example, the following is a property path for a binding that accesses the first item in a Validation.Errors collection; the context of the property path is modified by RelativeSource so that the errors are checked only at run time on the applied template:

<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Validation.Errors)[0].Exception.Message }">

Silverlight includes some properties where there is a text syntax that resembles a property path syntax because it is parsed to result in a "dot-down" traversal of an object model. However, these are not a true property path, in that the properties do not use the PropertyPath type. Examples of such properties are ItemsControl.DisplayMemberPath and Selector.SelectedValuePath. The usages described in this topic do not necessarily apply to such properties. Generally, such Path properties support a simple dot-down traversal of a CLR object model for their associated source, and do not support XAML namespace qualification or context deferral.

PropertyPath for Animation Targets

A property path is used to specify the property that is the target of an animation.

The target property of an animation must be a dependency property. The property that starts the path must resolve to the name of a dependency property that exists on the type specified by Storyboard.TargetName. The targeted property on a type and the eventual animated property can exist on different objects, which is the primary scenario for why property paths are used for animation targeting.

In syntax that follows, the placeholder animation represents one of several possible animation declarations, for example a DoubleAnimation, or PointAnimationUsingKeyFrames.

You can use the following syntaxes to specify a property path for an animation target:

  • Single property on the target object.

  • Indirect property targeting.

  • Attached property.

  • Indexer.

Single Property on the Target Object

<animation Storyboard.TargetProperty="propertyName" .../>

propertyName must resolve to the name of a dependency property that exists on the type specified by Storyboard.TargetName.

Indirect Property Targeting

<animation Storyboard.TargetProperty="(objectType.propertyName).propertyName2" .../>

objectType must be the type name of a type that has propertyName available as a member.

propertyName must be a property that exists on the type specified by Storyboard.TargetName.

propertyName2 must be the name of a dependency property that exists on the object that is the value of propertyName. In other words, propertyName2 must exist as a dependency property on the type that is the propertyName property type.

Indirect targeting of animations is necessary because of applied styles and templates. In order to target an animation, you need a TargetName on a target object, and that name is established on the target by x:Name or Name. Although template and style elements also can have names, those names are valid only within the XAML namescope of the style and template. (Styles and templates are literally shared between instances and would perpetuate duplicate names if XAML namescopes were extended here.) Thus, if the individual properties of an element that you want to animate come from a style or template, you need to start with a named element instance that is not from a style template. You then specify a path into the applied template-created visual tree that exists at run time to target the property you wish to animate.

For example, the Background property of a Panel is a complete Brush (actually a SolidColorBrush) that comes from a default template. To animate a Brush completely, there would need to be a BrushAnimation (probably one for every Brush type), but there is no such type. To animate a Brush, you instead animate properties of a particular Brush type. You need to get from SolidColorBrush to its Color to apply a ColorAnimation there. The property path for this example would be Background.Color.

In the multiple objects and subproperties form, you must use an owning object to disambiguate the initial property and place parentheses around this initial object.property combination. Thereafter, sub-properties need only be named, not qualified with owning types, but those subproperties must exist on the type of the preceding property in the property path. A slightly more verbose form that qualifies subsequent subproperty owning types is also acceptable; for example, "(Rectangle.Fill).(SolidColorBrush.Color)".

Attached Property

<animation Storyboard.TargetProperty="(ownerType.propertyName)" .../>

The parentheses indicate that this property in a PropertyPath should be constructed using an ownerType qualification, not a traversal. It can use an XML namespace to find the type. The ownerType searches types that a XAML processor has access to, through the XmlnsDefinitionAttribute declarations in each assembly. Most applications have the default XML namespace mapped to the Silverlight client namespace, so a prefix is usually necessary only for custom types or types otherwise outside that namespace. propertyName must resolve to the name of a property that exists on the ownerType. The property specified as propertyName must be a DependencyProperty. (All Silverlight attached properties are implemented as dependency properties, so this is a concern only for custom attached properties.)

Indexer

<animation Storyboard.TargetProperty="propertyName.propertyName2[index].propertyName3" .../>

Most dependency properties do not support an indexer. An indexer in an animation path should be at an intermediate position between the property that starts the chain on the named target and the eventual animated property. In the syntax shown, that is propertyName2. For example, an indexer usage might be necessary if the intermediate property is a collection such as TransformGroup, in a property path such as RenderTransform.Children[1].Angle.

PropertyPath in Code

You can use the PropertyPath(String, array<Object[]) constructor for either data binding or animation targeting; use the preceding sections for guidance on the syntax to use for the constructor string parameter.

Because the second parameter of the PropertyPath(String, array<Object[]) constructor is a parameter array, the second parameter is effectively optional for most practical usages and is typically not specified.

In code, rather than using a property path string, you also have the option to create a PropertyPath by specifying a DependencyProperty identifier with the PropertyPath(Object) constructor. This is appropriate if you reference a single property and not a path that has intermediate properties. When you specify a PropertyPath by DependencyProperty identifier, there is no ambiguity regarding the owner type of the relevant dependency property.

Important noteImportant Note:

If you construct a PropertyPath from a DependencyProperty, that PropertyPath is not usable as a Binding.Path, it is only usable for animation targeting. The Path value for the constructed PropertyPath from a DependencyProperty is the string value (0), which is a sentinel value used by the binding engine for an invalid path.

See Also

Reference

Concepts