如何根据属性隐藏wpf数据网格列
本文关键字:数据 数据网 网格 wpf 隐藏 何根 属性 | 更新日期: 2023-09-27 18:04:02
我有以下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 Output窗口中得到以下绑定错误:
System.Windows。数据错误:4:找不到要绑定的源引用"RelativeSource FindAncestor"AncestorType = ' System.Windows。窗口",AncestorLevel ="1"。BindingExpression:路径= DataContext.Flag;DataItem =零;目标元素is 'DataGridTextColumn' (HashCode=44856655);目标属性为"可见度"(类型"可见度")
我的代码中关于Visibility
属性的错误是什么?
数据网格中的列是一个抽象对象,它不出现在可视化树中,因此您不能使用RelativeSource
绑定,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"/>
<!-- ... -->
很有趣。
我更喜欢一种更优雅的方法,包括使用Freezable
。
<Window.Resources>
<DiscreteObjectKeyFrame x:Key="FlagKey" Value="{Binding Flag}"/>
</Window.Resources>
<DataGridTextColumn ... Visibility="{Binding Value, Source={StaticResource FlagKey}, ...}" />
DataGridTextColumn的可见性不是一个DependencyProperty,不能被绑定。使用DataGridTemplateColumn并在模板中绑定控件的可见性。
编辑:实际上,这句话只适用于silverlight。要了解更多细节,请参阅另一个SO问题。
如何绑定DataGridColumn.Visibility?我问的是判断一个属性是否是依赖的最简单的方法。
我怎样才能最容易地确定一个属性是否是一个依赖属性?
H.B.提出的解决方案确实很好,具有真正的WPF MVVM精神。在可能的地方使用它。
在我的特殊情况下出了问题,所以我用不同的方式出来,因为我的项目不是严格的MVVM,所以我可以使用编码解决方案。
在CustomView。
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="MachinesColumn" ... />
...
在customview . example .cs中,我们有一个简单的属性可以直接改变列的可见性:
public Visibility MachinesColumnVisible
{
get { return MachinesColumn.Visibility; }
set
{
if (value == MachinesColumn.Visibility)
return;
MachinesColumn.Visibility = value;
}
}
如果您正在自动生成列,则可以使用一个事件:
https://learn.microsoft.com/en us/dotnet/api/system.windows.controls.datagrid.autogeneratingcolumn?view=net - 5.0
我正在更改为自动生成列和此事件来解决几个问题!也可以用来改变列的标题