How to show only certain columns in a DataGridView with custom objects

You can also use Attribute [Browsable(false)] on any property in the underlying Objects, as may be appropriate. This of course would preempt the column from being browse-able some other place, so you might find that undesirable.


Whenever I do this I usually make grid.DataSource the result of a LINQ projection on the objects.

So something like this:

grid.DataSource = objects.Select(o => new
    { Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();

The nice thing is that you can then set AutoGenerateColumns to true, which will generate columns based on the properties of the projected objects.

Edit:

The one downside to this approach is that by projecting everything into an anonymous object, you can have problems in situations where you need to access a specific object in a click event, for example.

In this case you may be better off defining an explicit view model and projecting your objects into those. E.g.,

class MyViewModel
{
    public int Column1 { get;set; }
    public int Column2 { get;set; }
}

grid.DataSource = objects.Select(o => new MyViewModel()
    { Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();

Edit 2:

MyViewModel represents all of the columns you want to display in the DataGridView. The example properties should of course be renamed to suit what you are doing. In general, the point of a ViewModel is to serve as a sort of converter that mediates between the model (in your case your list of objects) and the view.

If you are wanting to retain a reference to the underlying object, the best way might be to supply it via the constructor:

class MyViewModel
{
    public int Column1 { get;set; }
    public int Column2 { get;set; }

    ....

    private SomeType _obj;

    public MyViewModel(SomeType obj)
    {
        _obj = obj;
    }

    public SomeType GetModel()
    {
        return _obj;
    }
}

grid.DataSource = objects.Select(o => new MyViewModel(o)
    { Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();

The reason I have gone for a getter method to retrieve the underlying model object is simply to avoid a column being generated for it.


You can use databindings with AutoGenerateColumns = false and using DataPropertyName like this

grid.Columns["Column_name_1"].DataPropertyName = "public_property_1";
grid.Columns["Column_name_2"].DataPropertyName = "public_property_2";

This way only bound columns will be shown in the datagridview, and you can create the columns in the editor if you want. Public properties can be any public attribute within your object.

If you are editing your data from the datagridview, then you should use NotifyPropertyChanged in the set methods. Se my question/answer here where I explain this all the way down.