Is there a way to hide a specific column in a DataGrid when AutoGenerateColumns=True?

Viewed 22059

I have a WPF 4.0 DataGrid that is bound to a DataTable using AutoGenerateColumns=True. The columns are dynamic, however I know there is always going to be a column named ID and I would like to hide this column. Is there a way I can do this?

7 Answers

I achieved this using Browsable attribute and Visibility: Collapsed

Model

class CourseModel
{
    [Description("")]
    [ReadOnly(false)]
    public bool Select { get; set; } = true; // Checkbox

    [Description("Course ID")]
    [ReadOnly(true)]
    [Browsable(false)]
    public string ID { get; set; } // Hidden column

    [Description("Course Title")]
    [ReadOnly(true)]
    public string Title { get; set; }
}

Custom control extension:

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace MyProject.FrontEnd.Controls
{
    class CustomDataGrid : DataGrid
    {
        // Take attributes of POCO, if available (https://stackoverflow.com/a/17255496/979621)

        protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
        {
            try
            {
                base.OnAutoGeneratingColumn(e);
                var propertyDescriptor = e.PropertyDescriptor as PropertyDescriptor;
                e.Column.Header = propertyDescriptor.Description;
                e.Column.IsReadOnly = propertyDescriptor.IsReadOnly;
                e.Column.Visibility = propertyDescriptor.IsBrowsable 
                                      ? Visibility.Visible 
                                      : Visibility.Collapsed;
            }
            catch
            {
                // ignore; retain field defaults
            }
        }
    }
}

ViewModel

public ObservableCollection<CourseModel> Courses { get; set; }

XAML

<Window 
    ...
    xmlns:controls="clr-namespace:MyProject.FrontEnd.Controls" 
    ...
>
...
<controls:CustomDataGrid x:Name="courses" 
    ItemsSource="{Binding Path=Courses, Mode=TwoWay, 
                  NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}" />

I've recently done this and wanted to share my solution:

I just made a view model I wanted the datagrid to follow and for the fields I wanted it to ignore (that is, not auto generate columns for), simply set those fields to private. Worked like a charm and there's no need for unnecessary code.

For example, here's the view model I pass to the view that contains the datagrid. I get all I need by simply setting the fields I don't want as columns to private, shown on the "FullPath" field in my example. I understand this may not be possible in every scenario, but worked for me quite well.

namespace dev
{   
    /// <summary>
    /// View model for tag list view in data grid
    /// </summary>
    public class TagDataViewModel : BaseViewModel
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="path">The JSONPath to this item</param>
        public TagDataViewModel(string path)
        {
            FullPath = path;
        }

        /// <summary>
        /// Gets and sets the JSONPath to this item
        /// </summary>
        private string FullPath { get; set; }

        /// <summary>
        /// Gets the name
        /// </summary>
        public string Name => ProjectHelpers.GetPropertyValue(FullPath, "Name");

        /// <summary>
        /// Gets the address
        /// </summary>
        public string Address => ProjectHelpers.GetPropertyValue(FullPath, "Address");

        /// <summary>
        /// Gets the data type
        /// </summary>
        public string DataType => ProjectHelpers.GetPropertyValue(FullPath, "DataType");

        /// <summary>
        /// Gets the scan rate
        /// </summary>
        public string ScanRate => ProjectHelpers.GetPropertyValue(FullPath, "ScanRate");

        /// <summary>
        /// Gets the scaling type
        /// </summary>
        public string ScalingType => ProjectHelpers.GetPropertyValue(FullPath, "ScalingType");
    }
}
Related