I have some problems in understanding RelativeSource
binding behavior.
Below is the code that binds Label
content to StackPanel
Tag correctly:
<Window x:Class="Binding_RelativeSource.MainWindow" Tag="Window Tag">
<Grid Tag="Grid Tag">
<StackPanel Tag="StackPanel Tag" Height="100" HorizontalAlignment="Left" Margin="156,97,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
<Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=StackPanel},FallbackValue=BindingFailed}" Height="28" Name="label1" />
</StackPanel>
</Grid>
</Window>
Above code does not bind Grid
Tag, if I change AncestorType=Grid
and AncestorLevel=2
.
I have 2 questions:
I think I should change AncestorLevel to 2, to bind to Grid. But it
worked for AncestorLevel=1
. Why?
I am also not able to bind label to Window tag.Please suggest.
The AncestorLevel
is use to find the correct ancestor to bind to, this is because there could be more than one ancestor of that type.
Here is a scenario that shows this:
<Grid Tag="AncestorLevel 3">
<Grid Tag="AncestorLevel 2">
<Grid Tag="AncestorLevel 1">
<StackPanel Tag="StackPanel Tag" Height="100" HorizontalAlignment="Left" Margin="156,97,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
<Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=Grid},FallbackValue=BindingFailed}" Height="28" />
<Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=2,AncestorType=Grid},FallbackValue=BindingFailed}" Height="28" />
<Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=3,AncestorType=Grid},FallbackValue=BindingFailed}" Height="28" />
</StackPanel>
</Grid>
</Grid>
</Grid>
Result:
But you can simplify the code by using ElementName
binding, this uses the Name
of the element
Example:
<Window x:Class="WpfApplication9.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Name="MyWindow" Tag="This is the window">
<Grid Name="Grid1" Tag="First grid">
<Grid Name="Grid2" Tag="Second grid">
<Grid Name="Grid3" Tag="ThirdGrid">
<StackPanel Name="stackPanel1" Tag="StackPanel Tag" Height="160" HorizontalAlignment="Left" Margin="156,97,0,0" VerticalAlignment="Top" Width="200">
<Label Content="{Binding ElementName=MyWindow, Path=Tag}" Height="28" />
<Label Content="{Binding ElementName=Grid1, Path=Tag}" Height="28" />
<Label Content="{Binding ElementName=Grid2, Path=Tag}" Height="28" />
<Label Content="{Binding ElementName=Grid3, Path=Tag}" Height="28" />
<Label Content="{Binding ElementName=stackPanel1, Path=Tag}" Height="28" />
</StackPanel>
</Grid>
</Grid>
</Grid>
</Window>
Result:
If you want to bind back to the Window
you can still use FindAncestor
<Window x:Class="WpfApplication9.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Tag="This is the window">
<Grid>
<StackPanel Height="100" HorizontalAlignment="Left" Margin="156,97,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
<Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},FallbackValue=BindingFailed}" Height="28" />
</StackPanel>
</Grid>
Result:
Final conclusion from my end: It was VS2010 designer problem that it does not update RelativeSource binding for Window tag. It updates binding for other controls (I checked with Grid & StackPanel) in designer but for Winodw it gets updated at run time. Microsoft has done workaround in VS2012 for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With