官术网_书友最值得收藏!

Binding path syntax

Bindings can be declared either in longhand, defining an actual Binding element in the XAML, or in shorthand, using the markup language that is translated to a Binding element for us by the XAML. We'll primarily focus on the shorthand notation, as that is what we will predominantly use throughout the book.

The Binding.Path property is of type PropertyPath. This type supports a unique syntax that can be expressed in XAML using a XAML markup extension. While it can be confusing at times, there are specific rules that we can learn to make it easier. Let's investigate.

To start with, let's understand that the binding path is relative to the binding source and that the binding source is typically set by the DataContext property, or by the path itself. In order to bind to the whole binding source, we can specify our binding like this:

{Binding Path=.} 

It can also be specified like this:

{Binding .} 

Most simply, we can specify our binding like this:

{Binding} 

Note that explicitly declaring the Path property name in this syntax is optional when the path value is declared first. The three preceding examples are all equal. We will omit the Path property declaration in the bindings in this book for brevity. Let's now see the remaining property path syntax mini-language.

To data bind to most property paths, we use the same notation as we use in code. For example, when binding directly to the property of a data bound object, we just use the property name:

{Binding PropertyName} 

To data bind to the property of an object that is directly referenced by a property of our binding source, we again use the same syntax that we do in code. This is known as indirect property targeting:

{Binding PropertyName.AnotherPropertyName} 

Similarly, when data binding to an item in a collection, or a property of a collection item, we use the indexing notation from code. For example, this is how we access a property from the first item in our data bound binding source:

{Binding [0].PropertyName} 

Of course, if we want to access the second item, we use a key of 1 and use a key value of 2 if we want the third item and so on. Likewise, to indirectly target a property of a collection item, where the collection is a property of our binding source, we use the following syntax:

{Binding CollectionPropertyName[0].PropertyName} 

As you can see, we are freely able to combine these various syntactical options to generate more complex binding paths. Multi-dimensional collections are also accessed in the same way as we refer to them in code:

{Binding CollectionPropertyName[0, 0].PropertyName} 
{Binding CollectionPropertyName[0, 0, 0].PropertyName} 
... 

While discussing data binding to collections, note that there is a special forward slash (/) syntax that we can use to access the selected item at any time:

{Binding CollectionPropertyName/PropertyName} 

This particular example would bind to the PropertyName property of the current item of the collection specified by the CollectionPropertyName property. Let's take a quick look at a more practical example:

<StackPanel> 
  <ListBox ItemsSource="{Binding Users}" 
    IsSynchronizedWithCurrentItem="True" /> 
  <TextBlock Text="Selected User's Name:" /> 
  <TextBlock Text="{Binding Users/Name}" /> 
</StackPanel> 

In this basic example using our UsersViewModel, we data bind the Users collection to a listbox. Underneath, we output the value of the Name property from the currently selected item. Note the setting of the IsSynchronizedWithCurrentItem property, as without it, this forward slash binding would not work correctly.

Try removing the IsSynchronizedWithCurrentItem property from the example and running the application again and you will see that the current user's name will be output initially, but not updated after changes to the selected item.

Setting this property to True will ensure that the ItemCollection.CurrentItem property from the ListBox.Items collection is updated each time the selection changes. Note that we could also achieve this same output using the ListBox.SelectedItem property instead of this forward slash notation:

<StackPanel> 
  <ListBox Name="ListBox" ItemsSource="{Binding Users}"  
    IsSynchronizedWithCurrentItem="True" /> 
  <TextBlock Text="Selected User's Name:" /> 
  <TextBlock Text="{Binding SelectedItem.Name, ElementName=ListBox}" /> 
</StackPanel> 

The IsSynchronizedWithCurrentItem property is now not needed to update the selected user's name in the TextBlock, because the SelectedItem property will take care of that. However, setting it to True in this case will ensure that the first item in the ListBox is selected and that the TextBlock will initially output the name of that item's user. Let's continue looking at the forward slash notation.

If you are trying to data bind to a property of an item in a collection, where the collection is itself an item of a parent collection, we can use the forward slash notation multiple times in a single binding path:

{Binding CollectionPropertyName/InnerCollectionPropertyName/PropertyName} 

To clarify, this path would bind to the PropertyName property of the selected item of the collection specified by the InnerCollectionPropertyName property, which itself is the selected item of the collection specified by the CollectionPropertyName property.

Let's move on from collections now, to Attached Properties. In order to data bind to an Attached Property, we need to use a slightly different syntax from that used in code; we need to enclose the property name in parenthesis, along with the class name:

{Binding (ClassName.PropertyName)} 

Note that when the Attached Property is a custom-declared property, we must include the XAML namespace prefix inside the parenthesis with its separating colon:

{Binding (XmlNamespacePrefix:ClassName.PropertyName)} 

Typically, when binding to Attached Properties, we also need to specify the binding target as well as the target property. The binding target will generally either be the object that the binding is set on, or another UI element, so we tend to see the RelativeSource or ElementName properties being used in these situations:

{Binding Path=(Attached:TextBoxProperties.Label), 
  RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}

We'll see an extended version of this example later in the book, but in short, it binds to the TextBoxProperties.Label Attached Property of the parent control of type TextBox. It is called from within a ControlTemplate and so, the parent textbox is the templated parent of the control that is being data bound.

主站蜘蛛池模板: 双流县| 惠来县| 垦利县| 遂平县| 西盟| 临西县| 罗山县| 宾阳县| 安福县| 神农架林区| 旬邑县| 吴桥县| 绥滨县| 喜德县| 昌乐县| 读书| 尖扎县| 浦江县| 泾阳县| 崇州市| 屯昌县| 新泰市| 阳东县| 工布江达县| 霸州市| 靖江市| 屯昌县| 南宁市| 新疆| 宜良县| 剑河县| 新沂市| 浦北县| 沙河市| 肥乡县| 新野县| 大荔县| 精河县| 神池县| 手机| 成武县|