0

I have a Grid and a Quad. The Grid Layouts Quads in it.

class Grid : System.Windows.Forms.Control
    {
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }

        protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);

            int numControls = this.Controls.Count;

            if (numControls < 1)
            {
                return;
            }

            int size = this.Width / numControls;

            int i = 0;

            foreach (Control ctrl in this.Controls)
            {
                ctrl.Size = new Size(size, this.Height);
                ctrl.Location = new Point(i * size, 0);
                i++;
            }
        }
}

and

class Quad : System.Windows.Forms.Control
    {
        protected override void OnPaint(PaintEventArgs args)
        {
            base.OnPaint(args);

            Pen p = new Pen(new SolidBrush(Color.Black));

            int x = this.ClientRectangle.X;
            int y = this.ClientRectangle.Y;
            int w = this.ClientRectangle.Width;
            int h = this.ClientRectangle.Height;

            args.Graphics.DrawRectangle(p, x,y,w-1,h-1);
        }
    }

and in the Form I have

        this.quad1 = new Quad();
        this.SuspendLayout();

        grid1 = new Grid();
        grid1.Size = new Size(200, 200);

        for (int i = 0; i < 4; i++)
        {
            Grid grid_j = new Grid();
            for (int j = 0; j < 4; j++)
            {
                grid_j.Controls.Add(new Quad());
            }
            grid1.Controls.Add(grid_j);
        }

        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 261);
        this.Controls.Add(grid1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

protected override void OnLayout(System.Windows.Forms.LayoutEventArgs levent)
        {
             base.OnLayout(levent);

             this.grid1.Size = new Size(this.ClientRectangle.Width, this.ClientRectangle.Height);
             this.grid1.Location = new Point(0, 0);
        }

However, this does not work at all. As soon as one resizes the whole thing draws crazy Patterns.

Crazy patterns

Why is that? I tried Clearing the graphics but with no success (and I'd thought it's cleared automatically before the OnPaint?).

It seems that adding an "Invalidate" call fixes the Problem:

foreach (Control ctrl in this.Controls)
            {
                ctrl.Size = new Size(size, this.ClientRectangle.Height-10);
                ctrl.Location = new Point(i * size, 0);
                ctrl.Invalidate();
                i++;
            }

Is this the correct way to do it? Also, when do I have to invoke a further "Update"?

nvoigt
  • 75,013
  • 26
  • 93
  • 142
mroman
  • 1,354
  • 9
  • 14
  • `Invalidate()` tells the control to re-draw it self and the graphics don't get cleatred before `OnPaint`. – Haytam Sep 05 '18 at 10:07
  • Does invalidate propagate to children? (Does it propagate to parents?) – mroman Sep 05 '18 at 11:33
  • I believe ti does propagate to children (not parents). I'm not 100% sure but you can test it with a simple drawing. – Haytam Sep 05 '18 at 13:01
  • Painting is optimized by default, redrawing only the part that is revealed when the control is resized. In other words, it will not overpaint one of the edges of the rectangle, producing the smearing effect. This behavior is controlled by the ControlStyles.ResizeRedraw style for the control, it is off by default. Easiest way to turn it on is by adding `this.ResizeRedraw = true;` to the Quad class constructor. This increases the odds for noticeable flicker, if that's a problem then also add `this.DoubleBuffered = true;` – Hans Passant Sep 05 '18 at 17:20

0 Answers0