DataGridView with styles applied

I really like using .NET DataGridView because its relatively simple and clean.
However, some behavior is a bit confusing for a beginner coder like me.

One of the confusions is the cell styling. DataGridView offers some comprehensive styling but it has one limitation that is not well documented. For reason unknown to me, DataGridView – which has DataTable bound to it – will not apply some cell styles if it’s not visible.

You might ask “Who in the hell will set cell styles to an invisible DataGridView?” Well, I for one am. I have the tendencies to use multiple DataGridView in separate Forms, and I always use ShowDialog, which means the program will stop until the form is closed or any event handler is triggered. So I always populate the DataGridView before calling ShowDialog for its parent form. Unfortunately, up to the point of ShowDialog method is called, the DataGridView will remain in invisible state, and some styling will failed to apply.

This is a sample of that scenario:


Form FRM = new Form();
DataGridView DGV= new DataGridView();
DataTable DT = new DataTable();
DGV.Parent=FRM;

//Populate the data table
DT.Columns.Add(“Text”, typeof(string));
DT.Columns.Add(“Number”, typeof(int));
DT.Rows.Add(“Test”, 2);

DGV.DataSource = DT;

//set background color to cell[1,0]
DGV[1, 0].Style.BackColor = Color.Red;

FRM.ShowDialog();

Looking at that code, one will assume the cell on the first row – second column will have red background color. But no, its still in default color which is white. This is DataGridView known behavior and it is by design.

So the easiest solution for this behavior is to apply the style once the form is shown. We can make use of VisibleChanged event on the DataGridView, or the Shown event on its parent form. One disadvantage of VisibleChanged in this case is that it will trigger both when the DataGridView set to shown and set hide, but the advantage is its triggered by the intended object so we don’t need to set the DataGridView as public.

Back to the sample, to fix the program we need to add an event handler as follow:


static void DGVVisibleChanged(object sender, EventArgs e)
{
DataGridView d = (DataGridView)sender;
if (d.Visible == false) return;

d[1, 0].Style.BackColor = Color.Red;
}

And then we need to add this event handler to the DataGridView.VisibleChanged event, so a little editing need to be done on the original code:


Form FRM = new Form();
DataGridView DGV= new DataGridView();
DataTable DT = new DataTable();
DGV.Parent=FRM;

//Populate the data table
DT.Columns.Add(“Text”, typeof(string));
DT.Columns.Add(“Number”, typeof(int));
DT.Rows.Add(“Test”, 2);

DGV.DataSource = DT;

DGV.VisibleChanged += DGVVisibleChanged;

FRM.ShowDialog();

And that’s it, we have the DataGridView styling working.

Advertisements