[dba-VB] WinForms: What is the best event for custom drawing on a leftmost cell of DataGridView

Gustav Brock Gustav at cactus.dk
Wed Dec 1 06:24:03 CST 2010


Hi Shamil

I see. If you didn't need to draw your +/- you could just remove the row headers. Or could you do that and then use column 0 to simulate the row headers?

This:
http://webcache.googleusercontent.com/search?q=cache:lC1xHEMKuvUJ:dotnet.itags.org/web-forms/121172/+%22C%23%22+DataGridView+show+rowselector+arrow&cd=7&hl=da&ct=clnk&gl=dk

located in the Google cache suggests:

Handle the RowPostPaint event (Code Snippet):

void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
  e.PaintHeader(DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentBackground);
}

Also, I located this thread which, however, perhaps collides with your +/- drawing:

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/346e5839-1813-472b-8b3a-7344118819b3

You may have seen it before (I just googled) but the topic seems pretty close to that of yours.

/gustav


>>> shamil at smsconsulting.spb.ru 01-12-2010 12:49 >>>
Gustav --

I have currently used - Form.DefaultBackColor - that helped as my form
backcolor is the same as gridview's rowheaders backcolor (see code below) -
I'd still be interested is there a way to use .RowHeader cell's
Style.BackColor to paint row header background without row selection arrow.
There should be a "trick" I'm missing as .RowHeader cell's Style.BackColor
is equal to [Control] system color, which is R(0),G(0),B(0) when you get it
via code but it's in fact a very light gray color here. The trick should be
somehow related to the fact that I'm getting Graphics (g variable) from
GridView Handle, and then Style.BackColor becomes invisible - I should
probably get Graphics somehow else or convert color before using it but I do
not know how...

private void dataGridView1_RowPostPaint(object sender,
DataGridViewRowPostPaintEventArgs e)
{
      PlusMinusDrawer.Draw(dataGridView1, e, true, Form.DefaultBackColor); 
}


.....

    public class PlusMinusDrawer
    {
        public static void Draw(DataGridView grid, 
                 DataGridViewRowPostPaintEventArgs e, 
                 bool drawPlus, 
                 Color givenBackColor)
        {
            DataGridViewCell cell = null;
            Color usedBackColor = Color.LightGray;
            if (givenBackColor != null) usedBackColor = givenBackColor;

            if (e.RowIndex == 0)
            {
                cell = grid.TopLeftHeaderCell;
                //usedBackColor = cell.Style.BackColor;  
                drawPlusMinus(cell, 0, drawPlus, usedBackColor);
            }
            DataGridViewCell cell1 = grid.Rows[e.RowIndex].HeaderCell;
            //usedBackColor = cell1.Style.BackColor;
            drawPlusMinus(cell1, e.RowBounds.Y, drawPlus, usedBackColor);

        }

        private static void drawPlusMinus(DataGridViewCell cell, int offsetY, bool drawPlus, Color backColor)
        {
            Graphics g = null;
            System.Drawing.Pen pen = null;
            Brush brush = null;

            try
            {
                DataGridView grid = cell.DataGridView;

                Rectangle headerBounds = new Rectangle(2, offsetY + 2, cell.Size.Width - 4, cell.Size.Height - 4);

                brush = new System.Drawing.SolidBrush(backColor);

                g = Graphics.FromHwnd(grid.Handle);
                pen = new System.Drawing.Pen(Color.Black, 2F);

                g.FillRectangle(brush, headerBounds); 
                int offsetX = 0;

                int padX = 2;
                int padY = 2;

                int h2 = cell.Size.Height - padY * 2;
                int w2 = grid.RowHeadersWidth - padX * 2;
                int h = h2 / 2;
                int w = w2 / 2;

                int height = 14; // vertical line height
                int width = 14;  // horisontal line width

                System.Drawing.Point[] p = new System.Drawing.Point[4];

                // horizontal line
                p[0].X = 0 + offsetX + w - width / 2 + padY;
                p[0].Y = h + offsetY + padY;

                p[1].X = 0 + offsetX + w + width / 2 + padY;
                p[1].Y = h + offsetY + padY;

                g.DrawLine(pen, p[0], p[1]);

                if (drawPlus)
                {
                    // vertical line
                    p[2].X = w + offsetX + padX;
                    p[2].Y = 0 + offsetY + padY + h - height / 2;

                    p[3].X = w + offsetX + padX;
                    p[3].Y = 0 + offsetY + padY + h + height / 2;
                    g.DrawLine(pen, p[2], p[3]);
                }
            }
            finally
            {
                if (brush!= null) brush.Dispose();
                if (pen != null) pen.Dispose();
                if (g != null) g.Dispose();
            }
        }

    }

Thank you.

--
Shamil
 
-----Original Message-----
From: Shamil Salakhetdinov [mailto:shamil at smsconsulting.spb.ru] 
Sent: 1 ??????? 2010 ?. 14:25
To: 'Discussion concerning Visual Basic and related programming issues.'
Subject: RE: [dba-VB] WinForms: What is the best event for custom drawing
ona leftmost cell of DataGridView head

Hi Gustav --

Thank you for your sample code.

I have to simulate hierarchical GridView (just one level) using DataGridView
(I do not use third-party controls - that's my customer requirement).
I do use RowPostPaint event to draw (+) - collpased , and (-) - expanded row
sign on row header cells as well as on top-left cell - the latter is used to
note/control collapsed/expanded datagridview rows on first level.

All works fine except that I cannot find how to suppress/hide row selector
arrow - when I use:

- DataGridViewCell's .Style.BackColor to paint RowHeader cell's background
- SelectionMode = CellSelect
- ShowEditingIcon = False

the record selector is still visible.

I have to use custom color - Color.LightGray to paint it over.

Thank you.

--
Shamil




More information about the dba-VB mailing list