Click here to Skip to main content
15,886,788 members
Articles / Web Development / HTML
Tip/Trick

How to hide automaticaly columns in datagrid

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
19 Jul 2015CPOL2 min read 15.5K   2  
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

C#
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.

 

C#
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 

XML
<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.

 

C#
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

XML
<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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Softeam Cadextan
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --