首页 > 解决方案 > Panel onPaint 渲染伪影

问题描述

我创建了面板类“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;
            }
        }
    }
}

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

在此处输入图像描述

如何解决?

标签: c#onpaint

解决方案


.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 并在绘制之前根据自己的喜好对其进行调整。


推荐阅读