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?
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?
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");
}
}