Search code examples
c#user-controlsparent-childrepaintonpaint

A control disappears from parent UserControl after UserControl's OnRepaint event


I have a UserControl which has a button on it. On the UserControl OnPaint event I draw a rounded corner border (or a simple rectangle if the radius is zero) and then I fill the entire control. After these manipulations my Button (btnClose) disappears. How do I make my button visible again?

protected override void OnPaint(PaintEventArgs pe)
{
    using (System.Drawing.Pen p = new Pen(new SolidBrush(this.BorderColor)))
    {
        if (borderRadius > 0)
        {
            DrawRoundRect(pe.Graphics, p, 0, 0, this.Width - 1, this.Height - 1, borderRadius, this.FillColor);
        }
        else
        {
            this.BackColor = this.FillColor;
            pe.Graphics.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);
        }
        btnClose.Location = new Point(this.Width - btnClose.Width - BTN_MARGIN_DELTA, BTN_MARGIN_DELTA);
    }
    base.OnPaint(pe);
}

Just in case, the DrawRoundRect function:

void DrawRoundRect(Graphics g, Pen p, float X, float Y, float width, float height, float radius, Color _fillColor)
{
    using (GraphicsPath gp = new GraphicsPath())
    {
        gp.AddLine(X + radius, Y, X + width - (radius * 2), Y);
        gp.AddArc(X + width - (radius * 2), Y, radius * 2, radius * 2, 270, 90);
        gp.AddLine(X + width, Y + radius, X + width, Y + height - (radius * 2));
        gp.AddArc(X + width - (radius * 2), Y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
        gp.AddLine(X + width - (radius * 2), Y + height, X + radius, Y + height);
        gp.AddArc(X, Y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
        gp.AddLine(X, Y + height - (radius * 2), X, Y + radius);
        gp.AddArc(X, Y, radius * 2, radius * 2, 180, 90);
        gp.CloseFigure();

        using (SolidBrush brush = new SolidBrush(_fillColor))
        {
            g.FillPath(brush, gp);
            g.DrawPath(p, gp);
        }
    }
}

Solution

  • Try moving the location code to the resize method:

    protected override void OnResize(EventArgs e) {
      btnClose.Location = new Point(this.Width - btnClose.Width - BTN_MARGIN_DELTA, BTN_MARGIN_DELTA);
    }
    

    Moving controls in a paint event could cause recursive calls to the paint event. Only "paint" in a paint event.