How to hide wpf datagrid columns depending on a property

前端 未结 4 1848
迷失自我
迷失自我 2020-11-29 04:05

I have the following WPF sample program:

Xaml:



        
相关标签:
4条回答
  • 2020-11-29 04:33

    Solution proposed by H.B. is really good and has true WPF MVVM spirit. Use it where possible.

    In my particular case something went wrong so I came out with different way, as my project is not strict MVVM, so I can use coded solution.

    In CustomView.xaml name assigned to column:

    <DataGrid>
        <DataGrid.Columns>
            <DataGridTemplateColumn x:Name="MachinesColumn" ... />
            ...
    

    In CustomView.xaml.cs we have a simple property which directly changes visibility of column:

    public Visibility MachinesColumnVisible
    {
        get { return MachinesColumn.Visibility; }
        set
        {
            if (value == MachinesColumn.Visibility)
                return;
            MachinesColumn.Visibility = value;
        }
    }
    
    0 讨论(0)
  • 2020-11-29 04:41

    Visibility on DataGridTextColumn is not a DependencyProperty and can't be databound. Use a DataGridTemplateColumn and bind the visibility of the controls within the template.

    Edit: Actually, this statement only applies to silverlight. See this other SO question for further details.

    How to bind DataGridColumn.Visibility?

    I asked about the easiest way to tell whether a property is a dependency here.

    How can I most easily determine whether a property is a dependency property?

    0 讨论(0)
  • 2020-11-29 04:46

    A column in a datagrid is an abstract object which does not appear in the visual tree, thus you cannot use RelativeSource-binding, ElementName will not work either since it will not find a governing FrameworkContentElement so you are in kind of a bind.

    One way that works is via Source and x:Reference, for that you will need to name your window and move the column to its resources to avoid a cyclical dependency error:

    <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"/>
                    <!-- ... -->
    

    Great fun.

    0 讨论(0)
  • 2020-11-29 04:56

    I would prefer a more elegant approach which involves using a Freezable.

    <Window.Resources>
    
        <DiscreteObjectKeyFrame x:Key="FlagKey" Value="{Binding Flag}"/>
    
    </Window.Resources>
    
    
    <DataGridTextColumn ... Visibility="{Binding Value, Source={StaticResource FlagKey}, ...}" />
    
    0 讨论(0)
提交回复
热议问题