为啥这个 WinForms 窗口在拖动时会呈现工件?

Posted

技术标签:

【中文标题】为啥这个 WinForms 窗口在拖动时会呈现工件?【英文标题】:Why is this WinForms window rendering artifacts while dragging?为什么这个 WinForms 窗口在拖动时会呈现工件? 【发布时间】:2018-10-22 09:58:23 【问题描述】:

我支持用 VB.NET 编写并使用 Visual Studio 2015 构建的 .NET 4 WinForms 应用程序。在 Windows 7 中一切正常,但在我们的 Windows 10 测试中,在主应用程序窗口。发生在多台机器上(所有戴尔笔记本电脑)。快速拖动表单窗口,并越过主窗口的顶部或底部边缘(在屏幕截图中以黄色突出显示),会导致它崩溃并留下图形伪影,如下所示:

是否有可以调整的窗口属性或设置来防止这种情况发生?

谢谢!

【问题讨论】:

你在拖入一个可滚动的控件吗? 我将表单窗口拖到另一个具有项目行网格的窗口上,用户选择其中一个并单击打开按钮将项目详细信息加载到新表单窗口中),两者都在主窗口内,主窗口本身会像屏幕截图一样滚动。不知道这是否能回答你的问题。 这可能是因为您在拖动时触发的事件处理程序之一中有 Application.DoEvents 语句。您也可以尝试将表单的 DoubleBuffered 属性设置为 True 发布重复问题的最少代码。 @mdelvecchio,记事本暗示您尝试添加外部清单文件。很长一段时间以来,VS 都嵌入了一个默认清单,该清单将排除外部清单文件。在 VS 中打开项目,从 Project Menu->ProjNmae Properties->Application Tanb 点击“View Window Settings”按钮。 VS 2015 应该有一个用于 DPI 设置的默认块,但它们会被注释掉。删除应用程序块周围的<!----> 【参考方案1】:

重绘问题通常归因于主线程可能被锁定执行某些进程并且无法重绘。您是否在应用程序中使用多线程方法。一个好的起点是检查是否有任何东西锁定了主线程。

【讨论】:

【参考方案2】:

每个 WinForms 控件都有一个名为 DoubleBuffered 的属性。它旨在减少这种不希望的影响。 启用双缓冲时,渲染操作首先在内存中进行。然后只有最后一个应用于图形设备。更多详情here.

默认情况下,表单禁用双缓冲。因此,将表单的DoubleBuffered 属性设置为true 即可解决问题。

更新

我误读了DoubleBuffered 已设置的评论。请确保为您的 MDI 子窗体和 MDI 父窗体设置了 DoubleBuffered 属性。此外,请确保显卡的驱动程序是制造商提供的,而不是默认驱动程序。

【讨论】:

OP 在 cmets 中声明 DoubleBuffered 属性已设置为 true。 我会检查是否在其他表单上设置了属性并报告。 我仔细检查了所有的表格,他们使用的是 DoubleBuffered = true,所以不是这样。

以上是关于为啥这个 WinForms 窗口在拖动时会呈现工件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在呈现这个模态视图时会有延迟?

为啥我的 UIBarButtonItem 在呈现视图控制器时会进行动画滑入?

为啥一个简单的模态视图控制器在呈现和关闭时会滞后?

electron 在windows下窗口为啥不能拖动

为啥 WPF 中的鼠标位置不正确,而缩放桌面上的 Winforms 则不正确?

如何通过拖动扩展的窗口框架使 WPF 窗口可移动?