Here the purpose is to be able to bind a Command on a Button which is under 2 levels of ItemsControl without using the “Ancestor” stuff.
So the classic way of doing this:
the following should work :
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Client.Name}" />
But we can do something better and more readable.
Create a new helper class:
public class DataContextProxy : Freezable { #region Overrides of Freezable protected override Freezable CreateInstanceCore() { return new DataContextProxy(); } #endregion public object DataSource { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } public static readonly DependencyProperty DataProperty = DependencyProperty.Register("DataSource", typeof(object), typeof(DataContextProxy), new UIPropertyMetadata(null)); }
Then in the View, add a resource to this new helper class:
<UserControl.Resources> <helpers:DataContextProxy x:Key="DataContextProxy" DataSource="{Binding}"/> </UserControl.Resources>
Then in your Grid:
<ItemsControl Margin="5" ItemsSource="{Binding ClientRows}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <!--CLIENT--> <Border BorderBrush="LightGray" BorderThickness="1"> <StackPanel Orientation="Horizontal" Width="150"> <!--CLIENT NAME--> <TextBlock TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Text="{Binding Client.Name}" /> <!--BUTTONS--> <Button Height="23" Content="Delete Client" Command="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.DeleteClientCommand}" CommandParameter="{Binding}" Visibility="{Binding IsDeleteVisible}" /> ...
So here we don’t need anymore to know at which level of the binding we are.
We just call the Proxy (DataContextProxy) to set the binding.