Winforms 皮肤光滑的C#形状在调整大小时会出现巨大的黑色闪烁!

Winforms 皮肤光滑的C#形状在调整大小时会出现巨大的黑色闪烁!,winforms,visual-studio-2008,resize,flicker,skin,Winforms,Visual Studio 2008,Resize,Flicker,Skin,我试图用一种与您通常看到的不同的方法创建一些带蒙皮的表单(只是边框和标题),但是我在调整表单大小时遇到了表单闪烁的问题 我不知道如何解释这个问题,所以我制作了一个视频来演示这个问题: 此外,这里还有一个VS2008测试解决方案,其中包含重新绘制表单边框的全部代码: 希望有人能帮我摆脱闪烁…这就是我在基本表单的构造函数中使用的内容: this.SetStyle( ControlStyles.AllPaintingInWmPaint, true ); this.SetStyle( ControlS

我试图用一种与您通常看到的不同的方法创建一些带蒙皮的表单(只是边框和标题),但是我在调整表单大小时遇到了表单闪烁的问题

我不知道如何解释这个问题,所以我制作了一个视频来演示这个问题:

此外,这里还有一个VS2008测试解决方案,其中包含重新绘制表单边框的全部代码:


希望有人能帮我摆脱闪烁…

这就是我在基本表单的构造函数中使用的内容:

this.SetStyle( ControlStyles.AllPaintingInWmPaint, true );
this.SetStyle( ControlStyles.UserPaint, true );
this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );
this.SetStyle( ControlStyles.ResizeRedraw, true );

我认为关键在于使用“allpaintingwmpaint”。

如果要避免丑陋的未初始化黑色视频叠加闪烁,您必须放弃使用Form.TransparencyKey属性。它在您的示例程序中没有任何用处。

尝试启用双缓冲?

如果要使窗体具有不规则形状,您必须转向区域(如果您可以使用圆形和矩形等几何形状轻松定义窗体的区域)。创建System.Drawing.Graphics.Region对象并向其添加形状。我认为表单上的属性称为Region-将您创建的区域指定给它

您的另一个选择是使用分层窗口。某人分层窗口不适用于2000年以前的windows版本,但它们还有半透明的额外好处

最后一个选项是使用WPF并设置AllowTransparency=“True”WindowStyle=“None”。这将删除chrome(谷歌“chrome window WPF”有一百万个例子)


最后,如果你有勇气和耐心,你可以随时捕捉窗口后面的桌面,并在其他任何事情之前对其进行绘制。如果您的窗口移动,您将需要求助于一些奇特的黑客手段:我并不推荐这种方法,但您需要知道所有选项。

哦,顺便说一句,除非您将所有绘制逻辑都放在override OnPaint()中,否则使用SLIMcode的代码将无法工作。如果这听起来不熟悉,您可能不知道可以通过在表单上调用Invalidate()强制要求重新绘制。将代码重构为单个绘制方法是一项任务,但最终会产生更干净的代码。

(这是一个特定于Vista的解决方案;它仅在启用桌面合成时才起作用。)

看起来Windows通过将窗体原始边框上的像素复制到新区域来初始化已调整大小的窗体的内容。在您的例子中,新区域初始化为黑色很可能是因为表单的边界最初有黑色像素

要消除闪烁,只需将窗体中最右边和最下面的像素线始终设置为TransparencyKey——这将使新区域保持透明,直到有机会重新绘制它们为止。也就是说,使表格1像素比需要的更宽和更高,并将多余的像素涂成透明


示例:

要在调整win窗体大小时消除闪烁,请在调整大小时暂停布局。重写表单resizebegin/resizeend方法,如下所示

protected override void OnResizeBegin(EventArgs e) {
    SuspendLayout();
    base.OnResizeBegin(e);
}
protected override void OnResizeEnd(EventArgs e) {
    ResumeLayout();
    base.OnResizeEnd(e);
}

这将使控件保持不变(在调整大小之前),并在调整大小操作完成时强制重新绘制。

尽管如此,我不确定将所有逻辑放入OnPaint()是否会修复闪烁。这对我来说有点困惑,你能帮我举个例子吗?如果您可以使用我提供的测试解决方案并应用您的建议,那就太好了,因为我不确定该怎么办。我添加了一个示例(您的测试解决方案不再可用)。然而,我后来发现我的解决方案只能在启用桌面合成的Vista下工作。在没有dwm的XP和Vista下,你仍然会看到黑色闪烁。我有点忘了这一点,不知道你是否会看到它。。。但我无法访问您的示例…奇怪的是,正如您所说,这只适用于启用DWM的Vista,但我认为在启用DWM的Windows 7中也是如此,但事实并非如此…它没有解决问题,而且我不喜欢控件保持完整的事实。