Panel onPaint 渲染伪像

Panel onPaint render artefacts

我创建了面板 class“GpanelBorder”,它使用以下代码在自定义面板中绘制边框:

namespace GetterControlsLibary
{
    public class GpanelBorder : Panel
    {
        private Color colorBorder;
        public GpanelBorder()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawRectangle(
                new Pen(
                    new SolidBrush(colorBorder), 8),
                    e.ClipRectangle);
        }

        public Color BorderColor
        {
            get
            {
                return colorBorder;
            }
            set
            {
                colorBorder = value;
            }
        }
    }
}

工作正常,但当我在设计模式下,在面板内单击鼠标并移动鼠标或将其他控件拖到此面板上时,会创建工件(下图)

如何解决?

.ClipRectangle 参数不一定表示要在其中绘制的控件的整个区域。它可能代表控件的较小部分,表明仅需要重新绘制该部分。在计算和重绘整个控件的成本太高的情况下,您可以使用“剪辑矩形”仅重绘控件的一部分。如果这种情况不适用于您,则使用 ClientRectangle 获取整个控件的边界并使用它来绘制边框。此外,您正在泄漏笔和 SOLIDBRUSH。完成这些资源后,您需要 .Dispose()。这最好用 using 块来完成:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    using (SolidBrush sb = new SolidBrush(colorBorder), 8))
    {
        using (Pen p = new Pen(sb))
        {
            e.Graphics.DrawRectangle(p, this.ClientRectangle);
        }
    }
}

您可能需要在 ClientRectangle 的基础上创建一个新的 Rectangle,并在绘制前根据您的喜好进行调整。

谢谢,效果很好!

但正确的代码是

protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (SolidBrush sb = new SolidBrush(colorBorder))
            {
                using (Pen p = new Pen(colorBorder, 2))
                {
                    e.Graphics.DrawRectangle(p, this.ClientRectangle);
                }
            }
        }