Странное поведение OnPaint / OnLayout - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть решетка и квад. Квадратные схемы сетки в нем.

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++;
            }
        }
}

и

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);
        }
    }

и в форме у меня есть

        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);
        }

Однако это не работает вообще. Как только каждый изменяет размер всего рисует сумасшедшие узоры.

Crazy patterns

Почему это? Я попытался очистить графику, но безуспешно (и я подумал, что она очищается автоматически перед OnPaint?).

Похоже, что добавление вызова "Invalidate" решает проблему:

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++;
            }

Это правильный способ сделать это? Кроме того, когда мне нужно вызвать еще одно «Обновление»?

...