首先,DataGridTextColumn(或任何其他受支持的 dataGrid 列)不在DataGrid 的可视化树中。因此,默认情况下它不会继承DataGrid 的DataContext。但是,它仅适用于 Binding DP,不适用于 DataGridColumn 上的其他 DP。
由于它们不在同一个 VisualTree 中,任何使用 RelativeSource 获取 DataContext 的尝试都不会奏效,因为 DataGridTextColumn 无法遍历到 DataGrid。
还有其他两种方法可以实现这一点:
首先使用Freezable 类。 Freezable 对象可以继承 DataContext,即使它们不在可视化或逻辑树中——我们可以利用这一点。
首先,创建一个继承自 Freezable 和 Data DP 的类,我们可以使用它来绑定 XAML:
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy));
}
现在,在 DataGrid 资源中添加它的一个实例,以便它可以继承 DataGrid 的 DataContext 并可以与它的 Data DP 绑定:
<DataGrid>
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding Data.MyColumnVisibility,
Source={StaticResource proxy}}"/>
</DataGrid.Columns>
</DataGrid>
第二,您可以使用ElementName 或x:Reference 引用XAML 中的任何UI 元素。但是,ElementName 只能在同一个可视化树中工作,而 x:Reference 没有这样的限制。
所以,我们也可以利用它来发挥我们的优势。在 XAML 中创建一个虚拟 FrameworkElement,并将可见性设置为 collapsed。 FrameworkElement 将从其父容器继承 DataContext,该容器可以是 Window 或 UserControl。
并且可以在 DataGrid 中使用它:
<FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Test"
Binding="{Binding Name}"
Visibility="{Binding DataContext.IsEnable,
Source={x:Reference dummyElement}}"/>
</DataGrid.Columns>
</DataGrid>