Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to hide automaticaly columns in datagrid

0.00/5 (No votes)
19 Jul 2015 1  
This sample is about hiding automatically datagrid columns when all rows of this column are empty.NB: The following code is for silerlight 5 and can be readapt for WPF

Introduction

Sometimes we need to hide automatically columns that doesn’t have values in a datagrid. Not only the column visibility property cannot be bound in simple manner, but hiding it in runtime mode is a bit complex.

In fact, the datagrid columns are not part of visual or logical tree because they are abstract and so, binding the visibility property will be achieved with a little “verbosity coding”.

Using the code

First of all, let extend a grid column property like this

public class DataGridTextColumnExtended : DataGridTextColumn
{
    public static readonly DependencyProperty VisibiltyBindingProperty = DependencyProperty.Register(
            "VisibiltyBinding", typeof(Visibility), typeof(DataGridTextColumnExtended),
            new PropertyMetadata(OnVisibilityChanged));

    private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      ((DataGridTextColumnExtended)d).Visibility = (Visibility)e.NewValue;
    }
    public Visibility VisibiltyBinding
    {
       get { return (Visibility)GetValue(VisibiltyBindingProperty); }
       set { SetValue(VisibiltyBindingProperty, 

 

In my case, I just extend the DataGridTextColumn class, it’s recommended to use DataGridTemplateColumn instead as this class can contains more than simple text.

I create a dependency property to handle the visibility of the column. This one can now be bound on runtime without XamlParseException.

But, as we can only use a static datasource when binding, then I create a dependency object which behave as proxy.

 

public class DataContextProxy : DependencyObject
    {
        public static readonly DependencyProperty DataSoureceProperty =
                DependencyProperty.Register(
                "DataSource", typeof(object), typeof(DataContextProxy),
                new PropertyMetadata(new PropertyMetadata(null)));
        public object DataSource
        {
            get { return this.GetValue(DataSoureceProperty); }
            set { this.SetValue(DataSoureceProperty, value); }
        }
    }

So, I could define a static resource in my view which is bound on my datasource: just like this 

<helpers:DataContextProxy x:Key="DataProxy" DataSource="{Binding DataListModified}"/>

From now, I can use it as a source to bind the visibility of my grid column with a converter. The converter takes the datasource as value, and the column name as parameter; and with reflection, I use to determine if all rows of the column are empty or not.

 

public class GridRowVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || parameter == null)
            {
                return Visibility.Visible;
            }
            var data = value as IEnumerable<Person>;
            if (data != null)
            {
                var noEmpty = from d in data
                    let v = d.GetType().GetProperty(parameter.ToString()).GetValue(d, null)
                    where v != null && !string.IsNullOrEmpty(v.ToString())
                    select d;
                return noEmpty.Any() ? Visibility.Visible : Visibility.Collapsed;
            }
            return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Finally, the binding on the visibility of the grid column can be done as follow

<helpers:DataGridTextColumnExtended

                        Header="Phone number"

                        VisibiltyBinding="{Binding Source={StaticResource DataProxy},Path=DataSource,Converter={StaticResource GridRowVisibilityConverter}, ConverterParameter='Phone'}"                               

                        Binding="{Binding Phone}"/>
The source code can be found on this link: https://github.com/katoyi/SLWPFGrid.

Points of Interest

The main interesting part of this article is the converter class. In fact, the visibility can be managed in a classic MVVM by doing all check on datasource in the ViewModel, and bind the column visibility after all computation made in the ViewModel. This means having additionnal variables (one variable per column to hide).

History

 

 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here