WPF 中 DataGridColumn 的绑定可见性 [英] Binding Visibility for DataGridColumn in WPF
问题描述
如何通过绑定隐藏 WPF DataGrid
中的列?
How can I hide a column in a WPF DataGrid
through a Binding?
这就是我所做的:
<DataGridTextColumn Header="Column header"
Binding="{Binding ColumnValue}"
Width="100"
ElementStyle="{StaticResource DataGridRightAlign}"
Visibility="{Binding MyColumnVisibility}" />
这就是我得到的(除了列仍然可见):
And this is what I got (besides the column still visible):
System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement.BindingExpression:Path=MyColumnVisibility;数据项=空;目标元素是DataGridTextColumn"(HashCode=1460142);目标属性是可见性"(类型可见性")
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyColumnVisibility; DataItem=null; target element is 'DataGridTextColumn' (HashCode=1460142); target property is 'Visibility' (type 'Visibility')
如何修复绑定?
推荐答案
首先,DataGridTextColumn
(或任何其他支持的 dataGrid 列)不位于 <代码>数据网格代码>.因此,默认情况下它不继承DataGrid
的DataContext
.但是,它仅适用于 Binding
DP,不适用于 DataGridColumn 上的其他 DP.
First of all, DataGridTextColumn
(or any other supported dataGrid column) does not lie in the Visual tree of the DataGrid
. Hence, by default it doesn't inherit the DataContext
of the DataGrid
. However, it works for Binding
DP only and for no other DP's on DataGridColumn.
由于它们不在同一个 VisualTree 中,任何使用 RelativeSource
获取 DataContext
的尝试都不会奏效,因为 DataGridTextColumn
无法遍历到 DataGrid
.
Since they don't lie in the same VisualTree, any attempt to get the DataContext
using RelativeSource
won't work as well because DataGridTextColumn
is unable to traverse up to the DataGrid
.
不过,还有另外两种方法可以实现这一点:
There are two other ways to achieve this though:
首先使用 Freezable
类.Freezable
对象可以继承 DataContext,即使它们不在可视化或逻辑树中——我们可以利用这一点.
First using a Freezable
class. Freezable
objects can inherit the DataContext even when they’re not in the visual or logical tree –We can take advantage of that.
首先,创建一个继承自 Freezable
和 Data
DP 的类,我们可以使用它在 XAML 中进行绑定:
First, create a class inheriting from Freezable
and Data
DP which we can use to bind in 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 绑定:
Now, add an instance of it in DataGrid resources so that it can inherit the DataGrid's DataContext and can bind with its 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 没有这样的约束.
Second, you can refer to any UI element in XAML using ElementName
or x:Reference
. However, ElementName
works only in the same visual tree, whereas x:Reference doesn't have such constraints.
因此,我们也可以利用它来发挥我们的优势.在 XAML 中创建一个虚拟的 FrameworkElement
,并将可见性设置为 collapsed
.FrameworkElement 将从其父容器(可以是 Window 或 UserControl)继承 DataContext.
So, we can use that as well to our advantage. Create a dummy FrameworkElement
in XAML with Visibility set to collapsed
. The FrameworkElement will inherit the DataContext from its parent container, which can be a Window or UserControl.
并且可以在 DataGrid 中使用它:
And can use that in 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>
这篇关于WPF 中 DataGridColumn 的绑定可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!