In
a typical data binding, a property of one object is updated
automatically from a property of another object. The object providing
the data—a Slider, for example—is considered to be the source of the data binding; the object receiving the data (such as the TextBlock) is the binding target.
The source of a data binding is usually given a name:
<Slider Name="slider" . . . />
You can break out the target property as a property element and assign to it an object of type Binding:
<TextBlock . . . >
<TextBlock.Text>
<Binding ElementName="slider" Path="Value" />
</TextBlock.Text>
</TextBlock>
Use the ElementName property to indicate the name of the source element; use the Path property for the name of the source property, which is the Value property of the Slider. This type of binding is sometimes known as an element-name binding, because the binding source is a visual element that is referenced by name.
To make the syntax a little friendlier, Silverlight provides a markup extension for Binding
where the whole thing is defined within a set of curly braces. Here’s the shorter syntax:
<TextBlock . . . Text="{Binding ElementName=slider, Path=Value}" . . . />
Notice that the ElementName and Path settings are separated by a comma, and that the slider and Value names are no longer in quotation marks. Quotation marks never appear within the curly braces of a markup extension.
The SliderBindings program includes this binding and lets you experiment with some variations. Everything is in the XAML file:
Example 1. Silverlight Project: SliderBindings File: MainPage.xaml (excerpt)
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions>
<Slider Name="slider" Value="90" Grid.Row="0" Maximum="180" Margin="24" />
<TextBlock Name="txtblk" Text="{Binding ElementName=slider, Path=Value}" Grid.Row="1" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Rectangle Grid.Row="2" Width="{Binding ElementName=slider, Path=Value}" RenderTransformOrigin="0.5 0.5" Fill="Blue"> <Rectangle.RenderTransform> <RotateTransform x:Name="rotate" Angle="90" /> </Rectangle.RenderTransform> </Rectangle> </Grid>
|
The page contains a Slider with a range from 0 to 180, a TextBlock with its Text property bound to the Value property of the Slider, and a Rectangle with its WidthValue property. The Rectangle also has a RotateTransform that rotates the element by a constant 90°. property bound to that same
As you manipulate the Slider, the TextBlock displays the current value and the Rectangle height decreases and increases. (The Binding targets the Width property of the Rectangle but the Rectangle is rotated 90°.)
The order of the properties in the Binding markup extension doesn’t matter. You can put the Path property first:
<TextBlock . . . Text="{Binding Path=Value, ElementName=slider}"
In fact, if Path appears first, you can eliminate the “Path=” part and just use the property name:
<TextBlock . . . Text="{Binding Value, ElementName=slider}"
The Binding class first needs to find an element in the visual tree with the name of slider, and then it needs to use reflection to find the Value property in that element. I prefer the syntax where the order of the properties mimics the internal operation of the process:
<TextBlock . . . Text="{Binding ElementName=slider, Path=Value}"
Why is this property of Binding called Path and not Property? After all, Style has a property named Property. Why not Binding?
The simple answer is that the Path can be a composite of multiple property names. For example, suppose the Slider did not have a name. You can indirectly refer to the Slider by knowing that it is the first item in the Children collection of the element named ContentPanel:
Text="{Binding ElementName=ContentPanel, Path=Children[0].Value}"
Or, going up higher in the visual tree,
Text="{Binding ElementName=LayoutRoot, Path=Children[1].Children[0].Value}"
The components of the path must be properties or indexers connected by periods.