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.





