etaiso
etaiso

Reputation: 2746

How to set titles for DataGridView rows/columns

I have a DataGridView which I would like to set a title for the rows and columns, as in the following image: enter image description here

Text1 describes the meaning of the columns headers and Text2 for the rows.

My question is if that's possible and if so, how to do that (override the DataGridView draw event?) or what other alternatives can you offer to achieve this goal? I want it to be elegant and intuitive.

EDIT:

I ended up using the following code:

private void dataGridView_tagretTable_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        if (e.ColumnIndex == -1 && e.RowIndex == -1)
        {
            // Clear current drawing, to repaint when user change header width
            e.Graphics.Clear(System.Drawing.Color.White);

            string drawString = "Text1";

            System.Drawing.Font drawFont = new System.Drawing.Font("Arial", 8);
            System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
            System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat();

            // Measure string
            SizeF stringSize = new SizeF();
            stringSize = e.Graphics.MeasureString(drawString, drawFont);

            // offset from rectangle borders
            float offset = 3;

            // Set string start point
            float x = offset;
            float y = e.Graphics.ClipBounds.Height - stringSize.Height - offset;
            e.Graphics.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);

            drawString = "Text2";

            // Measure string
            stringSize = e.Graphics.MeasureString(drawString, drawFont);

            // Set string start point
            x = e.Graphics.ClipBounds.Width - stringSize.Width - offset;
            y = offset;
            e.Graphics.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);

            // Draw crossing line
            Pen myPen = new Pen(Color.Black);
            myPen.Width = 1;
            e.Graphics.DrawLine(myPen, new Point(0, 0), new Point(e.ClipBounds.Width, e.ClipBounds.Height));

            drawFont.Dispose();
            drawBrush.Dispose();
            drawFormat.Dispose();
            myPen.Dispose();

            // Set min row header width
            if (dataGridView_tagretTable.RowHeadersWidth < 150)
            {
                dataGridView_tagretTable.RowHeadersWidth = 150;
            }

            e.Handled = true;
        }
    }

Upvotes: 2

Views: 879

Answers (1)

Adam Houldsworth
Adam Houldsworth

Reputation: 64487

Quite easy (fortunately). Subscribe to the CellPainting event and look for row -1 and column -1, then paint:

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex == -1 && e.RowIndex == -1)
    {
        e.Graphics.FillRectangle(Brushes.Red, e.ClipBounds);
        e.Handled = true;
    }
}

Obviously, you need to paint the relevant details, I'm just doing a red rectangle. Make sure you mark the event as Handled = true otherwise the control will take over painting again.

Please see this MSDN Forums link for further details.

If you wish to do stuff like make that text editable generally, you will want to derive from the control completely and instead of using the event, override the backing method OnCellPainting and do it there. This will also then allow you to expose new properties for ColumnHeadersTitle and RowHeadersTitle.

Upvotes: 4

Related Questions