在调整窗口大小时,使用OnPaint()绘制残差

时间:2017-02-12 16:19:16

标签: c# winforms

我创建了一个绘制边框(包含两个矩形)的自定义面板。问题是,如果我调整窗口大小,仍然存在残留......就像Windows XP的Solitaire动画一样。请参见下面的截图。我将窗口调整到右侧。

有什么问题,我该如何解决?

Resized window to the right

protected override void OnPaint(PaintEventArgs e)
{
    var outer = ClientRectangle;
    outer.Width -= 1;
    outer.Height -= 1;
    var inner = outer;
    inner.X++;
    inner.Y++;
    inner.Width -= 2;
    inner.Height -= 2;

    e.Graphics.DrawRectangle(DarkPen, outer);
    e.Graphics.DrawRectangle(WhitePen, inner);

    base.OnPaint(e);
}

更新

起初我以为这是因为我没有删除以前绘制的矩形。所以我打电话给FillRectangle删除内部。

var contentArea = inner;
contentArea.X++;
contentArea.Y++;
contentArea.Width -= 2;
contentArea.Height -= 2;
e.Graphics.FillRectangle(SystemBrushes.Control, contentArea);

但它也没有用。控件似乎只绘制了新扩展的部分,而不是整个区域。

1 个答案:

答案 0 :(得分:4)

Form类已优化为容器控件。容器通常只有背景颜色来绘制。所以,正如你所注意到的那样,确实“只画了新扩展的部分”。或者更确切地说,它不会过度修复先前的像素,易于从产生的拖尾效果中识别出来。当你调整窗口大小时,将Winforms设计变得更加生动是一种有点微弱的尝试,当一个表单有很多控件并且非常明显时,绘画会成为一个瓶颈。

您必须将其ResizeRedraw属性设置为true,以便在必要时重绘其整个表面。将绘图代码精心设计并开始注意闪烁时,将DoubleBuffered属性设置为true可能不会受到影响。

所以,粗略地说:

    public Form1() {
        InitializeComponent();
        this.ResizeRedraw = true;
        this.DoubleBuffered = true;
    }

优化OnPaint()通常不是一种有回报的策略,Windows本身已经剪切了您在脏区域绘制的内容。