如何根据属性隐藏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属性的错误是什么?

如何根据属性隐藏wpf数据网格列

数据网格中的列是一个抽象对象,它不出现在可视化树中,因此您不能使用RelativeSource绑定,ElementName也不能工作,因为它不会找到一个控制FrameworkContentElement,所以您处于一种绑定。

工作的一种方式是通过Sourcex: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

我正在更改为自动生成列和此事件来解决几个问题!也可以用来改变列的标题