WPF 中 DataGridColumn 的绑定可见性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22073740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Binding Visibility for DataGridColumn in WPF
提问by ygoe
How can I hide a column in a WPF DataGrid
through a Binding?
如何DataGrid
通过绑定隐藏 WPF 中的列?
This is what I did:
这就是我所做的:
<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 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')
System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。BindingExpression:Path=MyColumnVisibility; 数据项=空;目标元素是“DataGridTextColumn”(HashCode=1460142);目标属性是“可见性”(类型“可见性”)
How to fix the binding?
如何修复绑定?
回答by Rohit Vats
First of all DataGridTextColumn
or any other supported dataGrid columns doesn't lie in Visual tree of DataGrid
. Hence, by default it doesn't inherit DataContext
of DataGrid
. But, it works for Binding
DP only and for not other DP's on DataGridColumn.
首先DataGridTextColumn
或任何其他受支持的 dataGrid 列不位于DataGrid
. 因此,在默认情况下它不会继承DataContext
的DataGrid
。但是,它Binding
仅适用于DP,不适用于 DataGridColumn 上的其他 DP。
Since, they doesn't lie in same VisualTree so any try to get DataContext using RelativeSource
won't work as well because DataGrid won't able to traverse up to DataGrid.
因为,它们不在同一个 VisualTree 中,因此任何使用 DataContext 的尝试RelativeSource
都不会奏效,因为 DataGrid 将无法遍历到 DataGrid。
There are two ways to achieve that though:
不过有两种方法可以实现:
Firstusing Freezable
class - Freezable
objects can inherit the DataContext even when they're not in the visual or logical tree. So, we can take advantage of that to our use.
首先使用Freezable
类 -Freezable
即使对象不在可视化或逻辑树中,它们也可以继承 DataContext。因此,我们可以利用它来使用。
First create class inheriting from Freezable
and Data
DP which we can use to bind in XAML:
首先创建继承自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));
}
Now, add an instance of it in DataGrid resources so that it can inherit DataGrid's DataContext and then can bind with its Data DP:
现在,在 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>
Second, you can refer to any UI element in XAML using ElementName
or x:Reference
. But ElementName
works only in same visual tree whereas x:Reference doesn't have such constraint.
其次,您可以使用ElementName
或引用 XAML 中的任何 UI 元素x:Reference
。但ElementName
仅适用于相同的可视化树,而 x:Reference 没有这样的约束。
So, we can use that as well to our advantage. Create dummy FrameworkElement
in XAML with Visibility set to collapsed. FrameworkElement will inherit DataContext from it's parent container which can be Window or UserControl.
因此,我们也可以利用它来发挥我们的优势。FrameworkElement
在 XAML 中创建虚拟对象,并将可见性设置为折叠。FrameworkElement 将从它的父容器(可以是 Window 或 UserControl)继承 DataContext。
And can use that in DataGrid:
并且可以在 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>
回答by Meysam Chegini
<Window.Resources>
<ResourceDictionary>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}" />
</ResourceDictionary>
</Window.Resources>
<!-- Necessary for binding to resolve: adds reference to ProxyElement to tree.-->
<ContentControl Content="{StaticResource ProxyElement}" Visibility="Collapsed" />
<mch:MCHDataGrid Height="350"
AutoGenerateColumns="False"
FlowDirection="LeftToRight"
ItemsSource="{Binding PayStructures}"
SelectedItem="{Binding SelectedItem}">
<DataGrid.Columns>
<DataGridTemplateColumn Width="70"
Header="name"
IsReadOnly="True"
Visibility="{Binding DataContext.IsShowName,
Source={StaticResource ProxyElement}}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FieldName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</mch:MCHDataGrid>
Sample of bound property in view model:
视图模型中绑定属性的示例:
private Visibility _isShowName;
public Visibility IsShowName
{
get { return _isShowName; }
set
{
_isShowName = value;
OnPropertyChanged();
}
}