如何根据属性隐藏wpf datagrid列
Posted
技术标签:
【中文标题】如何根据属性隐藏wpf datagrid列【英文标题】:How to hide wpf datagrid columns depending on a property 【发布时间】:2011-10-15 00:38:06 【问题描述】:我有以下 WPF 示例程序:
Xaml:
<Window x:Class="AncestorArie.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>
<Grid>
<DataGrid AutoGenerateColumns="False" Name="Blumen"
ItemsSource="Binding Leaves">
<DataGrid.Columns>
<DataGridTextColumn Binding="Binding Color"
Header="Farbe" Width="160" />
<DataGridTextColumn Binding="Binding Size"
Header="Größe" Width="60"
Visibility="Binding Path=DataContext.Flag,
RelativeSource=RelativeSource Findancestor,
AncestorType=x:Type Window,
Converter=StaticResource BoolToVis" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
后面的代码:
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
Flowers rose = new Flowers();
rose.Leaves = new ObservableCollection<Leaf>();
rose.Flag = false;
Leaf L1 = new Leaf();
L1.Color = "rot";
L1.Size = 3;
rose.Leaves.Add(L1);
Leaf L2 = new Leaf();
L2.Color = "gelb";
L2.Size = 2;
rose.Leaves.Add(L2);
this.DataContext = rose;
模型类是:
public class Leaf
public string Color get; set;
public int Size get; set;
public class Flowers
public bool Flag get; set;
public ObservableCollection<Leaf> Leaves get; set;
如您所见,如果 Flag
属性设置为 false,我想隐藏第二个数据网格列。但它不起作用。我在 Visual Studio 输出窗口中收到以下绑定错误:
System.Windows.Data 错误:4:找不到绑定源 参考'RelativeSource FindAncestor, AncestorType='System.Windows.Window',AncestorLevel='1''。 BindingExpression:Path=DataContext.Flag;数据项=空;目标元素 是 'DataGridTextColumn' (HashCode=44856655);目标属性是 “可见性”(类型“可见性”)
关于Visibility
属性的代码有什么问题?
【问题讨论】:
【参考方案1】:如果您要自动生成列,则可以使用一个事件:
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.datagrid.autogeneratingcolumn?view=net-5.0
我将更改为自动生成的列和此事件以解决几个问题!也可以用来改变列上的Header。
【讨论】:
鼓励链接到外部资源,但请在链接周围添加上下文,以便您的其他用户了解它是什么以及为什么存在。始终引用重要链接中最相关的部分,以防外部资源无法访问或永久离线。【参考方案2】:我更喜欢使用Freezable
的更优雅的方法。
<Window.Resources>
<DiscreteObjectKeyFrame x:Key="FlagKey" Value="Binding Flag"/>
</Window.Resources>
<DataGridTextColumn ... Visibility="Binding Value, Source=StaticResource FlagKey, ..." />
【讨论】:
AnjumSKhan :确实非常好。干净优雅。谢谢 这也适用于绑定代理不起作用的情况。刚刚试了一下——谢谢! 在 .Net 5 中测试过,效果很好。另外,它允许我基于一个公共属性一次隐藏几列。简单的智能解决方案。额外提示:如果要将布尔值转换为可见性,请使用 DiscreteObjectKeyFrame.Value 转换器:<DiscreteObjectKeyFrame x:Key="FlagKey" Value="Binding Flag, Converter=StaticResource BooleanToVisibilityConverter" />
【参考方案3】:
H.B. 提出的解决方案。真的很好,有真正的 WPF MVVM 精神。尽可能使用它。
在我的特殊情况下出了点问题,所以我想出了不同的方法,因为我的项目不是严格的 MVVM,所以我可以使用编码解决方案。
在 CustomView.xaml 中分配给列的名称:
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="MachinesColumn" ... />
...
在 CustomView.xaml.cs 中,我们有一个简单的属性可以直接改变列的可见性:
public Visibility MachinesColumnVisible
get return MachinesColumn.Visibility;
set
if (value == MachinesColumn.Visibility)
return;
MachinesColumn.Visibility = value;
【讨论】:
【参考方案4】:DataGridTextColumn 上的可见性不是 DependencyProperty,不能进行数据绑定。使用 DataGridTemplateColumn 并绑定模板内控件的可见性。
编辑:实际上,此声明仅适用于 Silverlight。有关详细信息,请参阅此其他 SO 问题。
How to bind DataGridColumn.Visibility?
我在这里询问了判断属性是否为依赖项的最简单方法。
How can I most easily determine whether a property is a dependency property?
【讨论】:
感谢您的回答。你能告诉我如何在 Xaml 中识别一个属性是否是依赖属性吗? 我得到一个 绑定错误 令人困惑(请参阅我的编辑)。看起来 WPF 会尝试将 Visibility 绑定到属性。如果一个属性根本无法绑定,我预计会出现不同的错误——比如“无法绑定”之类的。 其实是DP,否则会编译出错。 @H.B.我的错。这看起来像是 Silverlight 和 WPF 之间的区别。 感谢您的进一步解释!【参考方案5】:数据网格中的列是一个抽象对象,它不会出现在可视化树中,因此您不能使用RelativeSource
-binding,ElementName
也不起作用,因为它找不到管理 FrameworkContentElement,所以您在一种绑定。
一种可行的方法是通过Source
和x:Reference
,因为您需要命名您的窗口并将列移动到其资源以避免循环依赖错误:
<Window Name="_window" ...>
<Window.Resources>
<DataGridTextColumn x:Key="ThatPeskyColumn"
Binding="Binding Size"
Visibility="Binding DataContext.Flag, Source=x:Reference _window, Converter=StaticResource BoolToVis"/>
</Window.Resources>
<!-- ... -->
<DataGrid AutoGenerateColumns="False" Name="Blumen"
ItemsSource="Binding Leaves">
<DataGrid.Columns>
<StaticResource ResourceKey="ThatPeskyColumn"/>
<!-- ... -->
非常有趣。
【讨论】:
我知道,我参加聚会有点晚了,但是谢谢,伙计!附言我讨厌DataGrid
开发者。
自从我从 .NET 4 升级到 4.5.2 后,我似乎无法让它工作。有谁知道为什么?
@CamHart:你知道如何调试绑定吗?
@H.B.不,我没有。我试图启动第二个 VS,并附加到第一个 VS 上运行的进程。但我永远无法触发任何错误。不过我确实找到了解决方案,***.com/questions/34817417/…。
@H.B.如果绑定是在单独的 xaml 文件的单独 ResourceDictionary 中的 以上是关于如何根据属性隐藏wpf datagrid列的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 MVVM 自动隐藏 WPF 中的 DataGrid 列? [复制]