错误或我做错了什么? Usercontrol绘画

时间:2011-05-17 13:18:45

标签: c# .net winforms windows-forms-designer paint

private void UserControl1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawEllipse(Pens.Black, new Rectangle(-200, -500, this.Width + 400, this.Height + 420));
}

将上述代码粘贴到usercontrol中。将usercontrol放到表单上并将其锚定到所有4个点。

在设计器中(在Visual Studio 2010下),它可以完美呈现(即使在您调整大小时)。运行它并尝试调整窗体大小,椭圆变得偏斜。

以下两个示例调整大小后第一个在运行时,第二个在设计器中。

Running After Resize Designer After Resize

显然,设计师的行为并不总是被认为是相同的(尽管它会很好)但我的理解是上面的代码是完全合法的。我错了吗?

2 个答案:

答案 0 :(得分:7)

Stecya has posted“修复”,但省略了详细解释为什么有效的说明或为什么你看到设计师的行为与在正在运行的应用程序在我看来,这使得答案只有最低限度的用处,所以我认为我会试图解释一下。

您已经知道调用Invalidate method是解决方案。这样做是告诉Windows,下次窗口被绘制时需要重新绘制控件的整个表面区域。很简单,但为什么你不必在设计师中这样做呢?

答案在于您在启用Windows Aero主题的情况下运行该程序。 Aero使用一个全新的窗口管理器,基于组合称为Desktop Window Manager(简称DWM)。每个窗口都是双缓冲的,这意味着它的图形会在屏幕外呈现为临时位图,然后才会显示在屏幕上。这允许用户现在喜欢的各种酷炫效果和花哨的过渡。

但是,当然,这意味着已经已经绘制的部分不会被删除并重绘,除非您明确指示Windows需要这样做。这对于设计器内部的表单来说不是问题,因为在那里,Aero的DWM组合未启用。当窗口调整大小时,它会自动重绘,你的旋风看起来很平滑和正确。

设计器的

外部,启用Aero组合后,只重新绘制控件的新曝光部分(其余部分仍在缓冲区中),所以形状错了。部分旧形状仍然存在,并且刚刚绘制了新形状的一部分。调用Invalidate告诉Windows“此控件的图形表面已更改;忘记您认为已知的所有内容并从中重绘下次划伤“。因此,Windows尽职尽责,从屏幕外缓冲区中丢弃该部分,并从头开始重绘,生成正确渲染,平滑的路径。

您可以用另一种更优雅的方式实现相同的更改:告诉控件它需要重新绘制自己每个时间调整大小。将以下代码插入控件的构造函数方法中:

public MyUserControl()
{
    // Force the control to redraw itself each time it is resized
    this.SetStyle(ControlStyles.ResizeRedraw);
}

答案 1 :(得分:4)

您可以在调整大小时手动取消控制

private void Form1_Resize(object sender, EventArgs e)
{
    userControl11.Invalidate();
}
相关问题