如何根据属性隐藏wpf datagrid列

Hul*_*lda 19 c# data-binding wpf xaml datagrid

我有以下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>
Run Code Online (Sandbox Code Playgroud)

代码背后:

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;            
    }
}
Run Code Online (Sandbox Code Playgroud)

模型类是:

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; }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,如果Flag属性设置为false ,我想隐藏第二个datagrid列.但它不起作用.我在Visual Studio输出窗口中收到以下绑定错误:

System.Windows.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Window',AncestorLevel ='1''.BindingExpression:路径= DataContext.Flag; 的DataItem = NULL; target元素是'DataGridTextColumn'(HashCode = 44856655); 目标属性是"可见性"(类型"可见性")

关于Visibility属性的代码有什么问题?

H.B*_*.B. 49

数据网格中的一个列是一个抽象对象,它不会出现在可视化树中,因此您不能使用RelativeSource-binding,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"/>
                <!-- ... -->
Run Code Online (Sandbox Code Playgroud)

非常有趣.

  • 我知道,我在聚会上有点迟到,但谢谢,伙计!PS我讨厌`DataGrid`开发人员. (4认同)

Anj*_*han 6

我希望使用一种更优雅的方法,其中涉及使用Freezable

<Window.Resources>

    <DiscreteObjectKeyFrame x:Key="FlagKey" Value="{Binding Flag}"/>

</Window.Resources>


<DataGridTextColumn ... Visibility="{Binding Value, Source={StaticResource FlagKey}, ...}" />
Run Code Online (Sandbox Code Playgroud)