How to hide column of DataGridView when using custom DataSource?
Asked Answered
F

10

31

I have a small app in c#, it has a DataGridView that gets filled using:

grid.DataSource = MyDatasource array;

MyClass hold the structure for the columns, it looks something like this:

class MyDatasource
{
    private string column1;        
    private string column2;

    public MyDatasource(string arg1, string arg2)
    {
        this.column1 = arg1;
        this.column2 = arg2;
    }

    public string column1
    {
        get
        {
            return this.column1;
        }
        set
        {
            this.column1 = value;
        }
    }

    public string column2
    {
        get
        {
            return this.column2;
        }
        set
        {
            this.column1 = value;
        }
    }
}

Everything works fine and the DataGridView gets populated with the correct data, but now I want to hide the column2. I tried adding [Browsable(false)] above the column declaration, that will hide it, but I also need to access the column value from code, and when I use [Browsable(false)] and try to read the content it acts like if the column doesn't exist. If I don't use it I can read the column without problem but it's visible in the DataGridView.

How could I hide the column but still be able to read its content from code?

Flamen answered 5/8, 2011 at 18:9 Comment(0)
S
50

In some cases, it might be a bad idea to first add the column to the DataGridView and then hide it.

I for example have a class that has an NHibernate proxy for an Image property for company logos. If I accessed that property (e.g. by calling its ToString method to show that in a DataGridView), it would download the image from the SQL server. If I had a list of Company objects and used that as the dataSource of the DataGridView like that, then (I suspect) it would download ALL the logos BEFORE I could hide the column.

To prevent this, I used the custom attribute

 [System.ComponentModel.Browsable(false)]

on the image property, so that the DataGridView ignores the property (doesn't create the column and doesn't call the ToString methods).

 public class Company
 {
     ...
     [System.ComponentModel.Browsable(false)]
     virtual public MyImageClass Logo { get; set;}
Scud answered 18/1, 2013 at 7:19 Comment(5)
This is definitely the best way to do it if your working with a property you know you will never want to display.Carolinacaroline
This is the best Answer. Period.Ely
I've used this before on Windows forms, but unfortunatelly it does not work on WPFSpoil
I'd say that's a bug in WPF then. I seem to remember microsoft considering to discontinue WPF a few years ago - I never got into WPF because of that...Scud
Also it makes the prop hidden for a BindingSource :(Hudnut
H
42

You have to hide the column at the grid view control rather than at the data source. Hiding it at the data source it will not render to the grid view at all, therefore you won't be able to access the value in the grid view. Doing it the way you're suggesting, you would have to access the column value through the data source as opposed to the grid view.

To hide the column on the grid view control, you can use code like this:

dataGridView1.Columns[0].Visible = false;

To access the column from the data source, you could try something like this:

object colValue = ((DataTable)dataGridView.DataSource).Rows[dataSetIndex]["ColumnName"];
Hypersthene answered 5/8, 2011 at 18:29 Comment(1)
'Visible' is "ReadOnly" after the control is created.Isonomy
S
6

I have noticed that if utilised progrmmatically it renders incomplete (entire form simply doesn't "paint" anything) if used before panel1.Controls.Add(dataGridView); then dataGridView.Columns["ID"].Visible = false; will break the entire form and make it blank, so to get round that set this AFTER EG:

 panel1.Controls.Add(dataGridView);
 dataGridView.Columns["ID"].Visible = false; 
 //works

 dataGridView.Columns["ID"].Visible = false; 
 panel1.Controls.Add(dataGridView);
 //fails miserably
Stroman answered 3/8, 2016 at 11:17 Comment(0)
R
5

I"m not sure if its too late, but the problem is that, you cannot set the columns in design mode if you are binding at runtime. So if you are binding at runtime, go ahead and remove the columns from the design mode and do it pragmatically

ex..

     if (dt.Rows.Count > 0)
    {
        dataGridViewProjects.DataSource = dt;
        dataGridViewProjects.Columns["Title"].Width = 300;
        dataGridViewProjects.Columns["ID"].Visible = false;
    }
Roup answered 10/12, 2012 at 17:21 Comment(0)
B
3

Set that particular column's Visible property = false

dataGridView[ColumnName or Index].Visible = false;

Edit sorry missed the Columns Property dataGridView.Columns[ColumnName or Index].Visible = false;

Britneybritni answered 5/8, 2011 at 18:27 Comment(0)
A
1

I had the same problem

Here is the Solution that might work for you. It worked for me

    GridView1.DataBind();
if (GridView1.Columns.Count > 0)
    GridView1.Columns[0].Visible = false;
else
{
    GridView1.HeaderRow.Cells[0].Visible = false;
    foreach (GridViewRow gvr in GridView1.Rows)
    {
        gvr.Cells[0].Visible = false;
    }
}
Argillaceous answered 15/4, 2013 at 12:3 Comment(0)
J
0

Just set DataGridView.AutoGenerateColumns = false;

You need click on the arrow on top right corner (in datagridview) to add columns, and in DataPropertyName you need to put a name of your property in your class.

Then, after you defined your columns in datagridview, you can set datagridview.datasource = myClassViewModel.

Jamilla answered 26/4, 2019 at 14:18 Comment(1)
".....you need to put a name of your property in your class.".... I posted: "you need to put the SAME name of your property in your class...." If my class has public string name {get;set;} then your DataPropertyName in column should has "name" value.Jamilla
E
0

MyDataGridView.RowHeadersVisible = False; Before binding and rename each columns header and set columns width. To help my failing memory when I search, because I will search ... that's for sure ;-)

Eal answered 16/1, 2021 at 19:37 Comment(0)
P
0

If you want to use the BrowsableAttribute, then you can look for it at runtime on the model and hide the column accordingly:

private void Form_Load(object sender, EventArgs e)
{
    //add this line after your DataGridView initialization
    HideColumns<MyModel>(myDvg);
}

private void HideColumns<T>(DataGridView dvg)
{
    var type = typeof(T);
    foreach (var column in dvg.Columns.Cast<DataGridViewColumn>())
        column.Visible = IsBrowsable(type.GetProperty(column.Name));
}

private bool IsBrowsable(PropertyInfo propertyInfo)
{
    var attribute = propertyInfo.GetCustomAttributes(true).FirstOrDefault(att => att.GetType() == typeof(BrowsableAttribute));
    return attribute == null || (attribute as BrowsableAttribute).Browsable;
}
Pettway answered 21/2, 2021 at 22:19 Comment(0)
S
0

Try follow:

DataGridView1.Columns["YourColumnName"].Visible = false;
Stickup answered 14/11, 2021 at 8:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.