首先DataGridTextColumn
或其他任何受支持的dataGrid列都不位于的可视树中DataGrid
。因此,在默认情况下它不会继承DataContext
的DataGrid
。但是,它Binding
仅适用于DP,而不适用于DataGridColumn上的其他DP。
因为它们并不位于同一VisualTree中,所以使用DataContext进行的任何尝试RelativeSource
都将无法正常工作,因为DataGrid无法遍历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,然后可以与其数据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
或引用XAML中的任何UI元素x:Reference
。但是ElementName
只能在同一视觉树中使用,而x:Reference没有这种约束。
因此,我们也可以利用该优势。FrameworkElement
在“可见性”设置为“折叠”的XAML中创建虚拟对象。FrameworkElement将从其父容器(可以是Window或UserControl)继承DataContext。
并可以在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>
x:Name
加上一个对其Visibility
属性的引用。并不是真正的直截了当,而是更多地转向侧面,但是仍然很简单。我猜想,当绑定到被引用元素的DataContext属性时,您会“劫持”另一个元素以与否则无法访问的DataGridColumn共享其DataContext,对吗?dummyElement只是桥梁。