
























In part 1, I gave a general finding rule for ElementName binding, it works in most cases, however there are some cases you cannot explain them with the general rule. I will cover some of them in the following articles which involve some advanced concept in WPF, like BindingExpression and InheritanceContext.
Take a look at following codes:
<Window x:Class="TestElementBindingInUserControl.MainWindow"> <local:CustomControl1/>
</Window>
<Style TargetType="{x:Type local:CustomControl1}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:CustomControl1}"> <StackPanel> <Button Name="btn" Content="PFS Button"/> <TextBlock Name="tbk" /> </StackPanel> <ControlTemplate.Triggers> <DataTrigger Binding="{Binding ElementName=btn, Path=Content}" Value="PFS Button"> <Setter TargetName="tbk" Property="Text" Value="PFS TextBlock"/> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
Let’s go back to our rules first:
If we start from DataTrigger, you will find its logic parent would be null, the search will not continue. Ok, I have to acknowledge the original statement is oversimplified.
It actually starts form the TargetElement of the BindingExpression which is created by the ElementName Binding. Here it is the CustomControl1. A little confused here? Let’s see what’s the BindingExpression and what’s the relationship between a BindingExpression and Binding.
Binding class is the high-level class for the declaration of a binding; the Binding class provides many properties that allow you to specify the characteristics of a binding. A related class,BindingExpression, is the underlying object that maintains the connection between the source and the target. Normally BindingExpression is created by WPF framework, WPF programmer rarely use it in functional codes. A key difference between BindingExpression and Binding is that Binding only contains the Source info while BindingExpression also contains the Target info. That is being said, Binding only tells you where the data comes from, while BindingExpression also defines where the data will transfer to.
In most cases, the TargetElement of the BindingExpression will be the DependencyObject whose DependencyProperty is set to a Binding MarkupExtension. For example, the TargetElement of the BindingExpression will be set to the Button object in following codes:
<Button Content="{Binding ElementName=root,Path=Title}"/>
However our style of CustomControl1, DataTrigger is not a DependencyObject and Binding property is not a DependencyProperty either.
<DataTrigger Binding="{Binding ElementName=btn, Path=Content}" Value="PFS Button">
The BindingExpression will be created in a different way than others, it’s created in StyleHelper.GetDataTriggerValue methods which are internal to the WPF framework. In that method, the BindingExpression’s TargetElement will be set to the object which applies the style that defines the DataTrigger.
Ok. We are clear of where should we start the search, let’s continue our search. CustomControl1 doesn’t own a NameScope, so we will get his parent which is Window, since Window has a NameScope, we will call the FindName method on Window’s NameScope, but we still cannot find btn. As I said both Window and ControlTemplate have their own NameScope, btn is registered in ControlTemplate’s NameScope rather than Window, so you cannot find btn in Window’s NameScope.
But if you run the above code, you will see it works. Ok, there is another point i missed in part 1.
When we start the search from the TargetElement of the BindingExpression, it will check ResolveNamesInTemplate property of the BindingExpression, if it’s true, it will try to find the element defined in its template first. In our case, the BindingExpression is created from a DataTrigger, the ResolveNamesInTemplate is set to true in StyleHelper.GetDataTriggerValue method, now btn can be found.
Let’s revised the finding rule:
In part 3, I will give some introduction to InheritanceContext which is also called LogicalParent 2.0. :)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。