Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 还是我做错了什么?用户控制绘制_C#_.net_Winforms_Windows Forms Designer_Paint - Fatal编程技术网

C# 还是我做错了什么?用户控制绘制

C# 还是我做错了什么?用户控制绘制,c#,.net,winforms,windows-forms-designer,paint,C#,.net,Winforms,Windows Forms Designer,Paint,将上述代码粘贴到usercontrol中。将usercontrol放到表单上,并将其锚定到所有4个点 在设计器中(在Visual Studio 2010下),它可以完美地渲染(即使在调整大小时)。运行它并尝试调整形状的大小,椭圆就会倾斜 以下是两个调整大小后的示例,第一个在运行时,第二个在设计器中 显然,设计器中的行为不能总是被假定为相同的(尽管这会很好),但我的理解是,上面的代码是完全合法的。我错了吗?您可以在调整大小时手动使控件无效 private void UserControl1_P

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

在设计器中(在Visual Studio 2010下),它可以完美地渲染(即使在调整大小时)。运行它并尝试调整形状的大小,椭圆就会倾斜

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


显然,设计器中的行为不能总是被假定为相同的(尽管这会很好),但我的理解是,上面的代码是完全合法的。我错了吗?

您可以在调整大小时手动使控件无效

private void UserControl1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawEllipse(Pens.Black, new Rectangle(-200, -500, this.Width + 400, this.Height + 420));
}
“修复”,但省略了一个解释,详细说明了为什么这样做有效,或者为什么在设计器中的行为与正在运行的应用程序中的行为存在差异。在我看来,这使得答案的用处微乎其微,所以我想我应该权衡一下,尝试一个解释

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

答案在于,您运行的程序启用了Windows Aero主题。Aero使用了一种全新的基于合成的窗口管理器(简称DWM)。每个窗口都是双缓冲的,这意味着它的图形在屏幕外被渲染成一个临时位图,然后才快速显示到屏幕上。这使得现在的用户似乎喜欢各种各样的酷炫效果和奇特的过渡

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

在设计器之外,启用Aero composition后,只会重新绘制控件的新暴露部分(其余部分仍在缓冲区中),因此形状是错误的。旧形状的一部分还在那里,新形状的一部分刚刚被画进去。调用
Invalidate
告诉Windows“此控件的图形表面已更改;忘记您认为知道的所有内容,下次从头开始重新绘制”。因此,Windows尽职尽责地遵守,从其屏幕外缓冲区中丢弃该部分,并从头开始重新绘制,生成正确渲染、平滑的路径

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

private void Form1_Resize(object sender, EventArgs e)
{
    userControl11.Invalidate();
}
public MyUserControl()
{
    // Force the control to redraw itself each time it is resized
    this.SetStyle(ControlStyles.ResizeRedraw);
}