我创建了一个绘制边框(包含两个矩形)的自定义面板。问题是,如果我调整窗口大小,仍然存在残留......就像Windows XP的Solitaire动画一样。请参见下面的截图。我将窗口调整到右侧。
有什么问题,我该如何解决?
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);
但它也没有用。控件似乎只绘制了新扩展的部分,而不是整个区域。
答案 0 :(得分:4)
Form类已优化为容器控件。容器通常只有背景颜色来绘制。所以,正如你所注意到的那样,确实“只画了新扩展的部分”。或者更确切地说,它不会过度修复先前的像素,易于从产生的拖尾效果中识别出来。当你调整窗口大小时,将Winforms设计变得更加生动是一种有点微弱的尝试,当一个表单有很多控件并且非常明显时,绘画会成为一个瓶颈。
您必须将其ResizeRedraw属性设置为true,以便在必要时重绘其整个表面。将绘图代码精心设计并开始注意闪烁时,将DoubleBuffered属性设置为true可能不会受到影响。
所以,粗略地说:
public Form1() {
InitializeComponent();
this.ResizeRedraw = true;
this.DoubleBuffered = true;
}
优化OnPaint()通常不是一种有回报的策略,Windows本身已经剪切了您在脏区域绘制的内容。