DataGridTextColumn Visibility Problem

Mar 27, 2009 at 3:48 PM
Edited Mar 27, 2009 at 3:51 PM
I need to hide a column on a trigger.

But I figgured out that:
1) There is no Style for a DataGridColumn
2) After setting Visibility=Collapsed with CellStyle, ElementStyle, HeaderStyle on ReadOnly column the column hides. But other columns doesn't shift to hidden column's place. And a hole in a table doesn't look nice.
3) Setting Width=0 also doesn't solve the problem.

How to hide the column properly?

Test project:


            <Style x:Key="hiddenStyle" TargetType="FrameworkElement">
                <Setter Property="Visibility" Value="Collapsed" />
                    Header="Name Column"
                    Binding="{Binding Name}"
                    CellStyle="{StaticResource hiddenStyle}"
                    ElementStyle="{StaticResource hiddenStyle}"
                    HeaderStyle="{StaticResource hiddenStyle}"
                    Header="Value Column"
                    Binding="{Binding Value}"
Mar 27, 2009 at 7:27 PM
Where exactly do you want to add the trigger? Is it on cell level, row level or datagrid level. The solution depends on which level the trigger is.
Mar 27, 2009 at 7:57 PM
Edited Mar 27, 2009 at 8:06 PM
On the UserControl level that hosts DataGrid.
I thought that I can define a style that will watch for some Dependency Property (of enum type) and will switch visibility of some rows.

                    <Style x:Key="visibleOnPersonalMedicalRecordStyle" TargetType="FrameworkElement">
                        <Setter Property="Visibility" Value="Collapsed" />
                            <DataTrigger Value="PersonalMedicalRecord" Binding="{Binding ElementName=medicalRecordGrid, Path=State}">
                                <Setter Property="Visibility" Value="Visible" />

But it requires Style property for a Column (witch doesn't exist).
What are other options? If I knew how to hide column at each level you mentioned I wouldn't ask =)
Mar 27, 2009 at 9:17 PM
There are two options...

  1. Set the visibility of the column, by indexing into the columns collection of DataGrid like....

                <Setter Property="datagrid.Columns[2].Visibility" Value="Collapsed"/>
    But personally I dont like this approach.

    2.  Use ViewModel approach. Have some property on the DataContext of DataGrid and bind the Visibility of column to the property (I like this approach).

Mar 30, 2009 at 8:35 AM
Thanks for hints.

But first suggestion will not work - XAML syntax does not support methods or indexers.
There will be an error "Cannot resolve the Style Property 'Visibility'. Verify that the owning type is the Style's TargetType, or use Class.Property syntax to specify the Property."
Mar 30, 2009 at 12:40 PM
Second suggestion doesn't work either!

DataGridTextColumn is not inherited from FrameworkElement so this code:

                    Binding="{Binding Id}"
                    Visibility="{Binding IdVisibility}"

Will result in following error:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IdVisibility; DataItem=null; target element is 'DataGridTextColumn' (HashCode=41519911); target property is 'Visibility' (type 'Visibility')

The explanation is: WPF won't add inheritance context for custom classes in current version. And DataGridTextColumn is custom class (not inherited from FrameworkElement).

The question is still open. How to hide column?
Mar 30, 2009 at 1:26 PM
You can forward the DataContext to the columns as described in this blog post,  That should enable scenario 2.
Mar 30, 2009 at 3:39 PM
Smart workaround. Thanks.

I hope there will be some design improvements in .net 4.0 though.
Aug 5, 2009 at 9:53 AM

This is a wonderful workaround, however I have one question about how to make full use of it:

Now I am able to bind the Visibility property of a column and that works perfectly. However, some of my columns are generated dynamically in code-behind rather than in XAML by copying properties of an existing column, and I need to create binding for the Visibility of those columns too. Ideally I would do this by copying an existing column's binding (so that I only need to change things in one place), however creating a new binding in code-behind would be acceptable.

The problem is I cannot find a way to set (or get) the binding from a DataGridColumn.Visibility in code-behind, because objects of type Visibility do not have any binding and are not DependencyObjects, in theory. I suspect if it were a UIElement.Visibility object all would be fine, but it is not and I do not know how to turn it into one.

Any help would be appreciated. I am probably missing something obvious...