explore.net

February 11, 2011

Creating A Multiple Column Header Within DataGridView

Filed under: C#.Net — NisanthVijay @ 3:13 am

I had a need to create a grid with a column header that spanned four columns. Having done a lot of ASP.Net in the past (and HTML directly in the more distant past), and knowing that this is a very simple thing to do in that environment, I figured it would be just as simple in the WinForms environment using the DataGridView. As happens far more often than I’d like to admit, I was wrong, although not by much. It wasn’t as simple as I had hoped, but it really wasn’t all that bad. Read on:

Basically, all we need to do is handle the DataGridView’s Paint() event. Let’s say we want to span columns 3, 4, 5, and 6 with one header that says “My Big Header”. Within the Paint() event handler, we’ll get a handle to the header cell of the first column you wish to span (“Column 3”), and we’ll use that to determine the coordinates of the location on the grid at which we will begin our header text:

DataGridViewCell hc = grid1.Columns[“Column 3”].HeaderCell;
Rectangle hcRct = grid1.GetCellDisplayRectangle(hc.ColumnIndex, -1, true);

The first line of code should be self-explanatory. In the second line, we’re getting a Rectangle object based on the cell in question. Passing the column index and the row index (“-1” means the row header) to the DataGridView’s GetCellDisplayRectangle() method gets us there.

Next, we’ll use that Rectangle object to get another Rectangle that represents the entire area to be covered by our new Multi-Column-Header. We can do that like so:

int multiHeaderWidth = grid1.Columns[hc.ColumnIndex].Width + grid1.Columns[hc.ColumnIndex + 1].Width + grid1.Columns[hc.ColumnIndex + 2].Width + grid1.Columns[hc.ColumnIndex + 3].Width;

Rectangle headRct = new Rectangle(hcRct.Left, hc.ContentBounds.Y + 2, multiHeaderWidth, grid1.ColumnHeadersHeight);

headRct.Height -= 3;

As you can see, the first line above simply gets the total width of all four columns to be spanned. We then pass that variable along with the other three coordinates (left, top, and height) required to instantiate a Rectangle object. (We add 2 to the Y coordinate and subtract 3 from the Rectangle’s height in the next line to create a margin, so that our header cell’s top and bottom borders are still visible.)

Next we need to find the size our string will be based on its length and the font we’ll be using:

SizeF sz = e.Graphics.MeasureString(“My Big Header”, grid1.Font);

Then we figure out where the top will need to be in order to make it vertically centered:

int headerTop = Convert.ToInt32((headRct.Height / 2) – (sz.Height / 2)) + 2;

Then we set the background color to match the grid’s header color:

e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), headRct);

And finally, we draw the text, starting 2 pixels to the right of the left-most point of our rectangle so it looks nice:

e.Graphics.DrawString(“My Big Header”, grid1.ColumnHeadersDefaultCellStyle.Font, Brushes.Black, hcRct.Left + 2, headerTop);

Putting it all together, here’s our Paint() event handler:

private void grid1_Paint(object sender, PaintEventArgs e)
{
    DataGridViewCell hc = grid1.Columns[“Column3″].HeaderCell;
    Rectangle hcRct = grid1.GetCellDisplayRectangle(hc.ColumnIndex, -1, true);

    int multiHeaderWidth = grid1.Columns[hc.ColumnIndex].Width + grid1.Columns[hc.ColumnIndex + 1].Width + grid1.Columns[hc.ColumnIndex + 2].Width + grid1.Columns[hc.ColumnIndex + 3].Width;
    Rectangle headRct = new Rectangle(hcRct.Left, hc.ContentBounds.Y + 2, multiHeaderWidth, grid1.ColumnHeadersHeight);
    headRct.Height -= 3;

    SizeF sz = e.Graphics.MeasureString(“My Big Header”, grid1.Font);
    int headerTop = Convert.ToInt32((headRct.Height / 2) – (sz.Height / 2)) + 2;
    e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), headRct);
    e.Graphics.DrawString(“My Big Header”, grid1.ColumnHeadersDefaultCellStyle.Font, Brushes.Black, hcRct.Left + 2, headerTop);
}

And here’s a screenshot:

 Hope this helped. Enjoy!

About these ads

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: