What exactly does WPF Data Binding's "RelativeSource FindAncestor" do?
The best way is to give a name to UserControl
Create dependency property MyProperty in UserControl with two way binding and bind it in main Window, than bind in UserControl like this
<UserControl x:Name = "myControl">
<Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>
If you're trying to 'escape' from an ItemsControl
or DataGridView
to get to a Window
you may be finding that AncestorType of x:Type Window
doesn't work. Or at least doesn't seem to...
If this is the case you're probably running Blend or Visual Studio and expecting the data to be visible at design time - which it won't because VS + Blend both create their own instances that aren't really Windows. It will work at runtime just fine, but not during design mode.
There's a couple things you can do:
Wrap in a UserControl
Here's an alternative solution I've come up with. It has one advantage in that you're not referencing a
UserControl
orWindow
directly, so if you change the parent container your code won't break.<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:views="clr-namespace:MyWPFApplication.Views" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MyWPFApplication.Views.UPCLabelPrinterWindow" mc:Ignorable="d" x:Name="LayoutRoot" Title="UPCLabelPrinterWindow"> <views:DataContextWrapper> <DockPanel> ... </DockPanel> </views:DataContextWrapper>
Where DataContextWrapper
is just a Grid
namespace MyWPFApplication.Views {
public class DataContextWrapper : Grid
{
}
}
Then when you bind you do this :
<TextBlock Text="{Binding="{Binding DataContext.SomeText,
RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper},
Mode=FindAncestor}}" />
Note: if you want to bind to a property ON Window itself it's trickier and you should probably bind via a dependency property or something like that. But if you are using MVVM then this is one solution I found.