将 WinForms 应用程序从 .net 3.5 迁移到 4.7.2 后如何解决 window 绘画问题
How to troubleshoot window painting issues after migrating WinForms app from .net 3.5 to 4.7.2
我们刚刚将我们的 VS2019 开发环境迁移到一个大型(~700 kloc)遗留 Windows Forms 应用程序,从 .NET 3.5 到 .NET 4.7.2,并因一个 windows 表格,出现了两个非常奇怪的问题:
- A
ContextMenuStrip
编码为在 DataGridView
中的单元格中右键单击时出现,鼠标悬停时不会自动打开其子菜单(如果存在)- 需要单击。表面上编码相同的 ContextMenuStrip 在其他表单上表现正常。
- 从有问题的表单(来自所述 ContextMenuStrip)打开另一个表单,导致该表单上的控件未被绘制。如果激活另一个表单,然后重新激活打开的表单,则会出现控件。但是,以与其他表单完全相同的方式打开相同的表单会产生预期的行为。
我知道这里没有什么可继续的 - 我猜我们已经被 .net 3.5 和 4.7.2 之间的一些模糊变化绊倒了,但是 Google 博士没有透露任何线索到目前为止。
为了隔离问题而撕掉一些东西将非常困难 - 我们有各种继承的控件和自定义网格绘画,其中大部分是功能的关键。我没有尝试构建测试用例,因为相同的继承控件(使用 DataGridView 和 ContextMenuStrip)在同一应用程序的其他地方完美工作,创建测试表单似乎不会做任何事情,除了工作正常。
所以在这个阶段,如果能知道去哪里看,我将不胜感激。
环境:Visual Studio 2019 v16.11.10,.net 4.7.2,Windows Forms 应用程序,主要使用 VB.NET 编写,在某些 class 中使用了少量 C#图书馆。
我尝试过的事情:
- 大量谷歌搜索 .net 3.5 和 .net 4.7.2 之间的重大更改
- 注释掉 DataGridView 中的一些自定义绘画
- 在
x64
、x86
和 AnyCpu
平台之间切换
- 编译 .NET 4.8 而不是 4.7.2 - 行为没有区别。
...都无济于事。
非常感谢收到任何想法。我会根据任何建议的结果更新问题。
编辑:
- 更正了对 ToolStripMenu 的引用 - 应该是 ContextMenuStrip,正如@dr.null 评论的那样。
- 添加了另一个测试:针对 .NET 4.8 进行编译和 运行,正如@dr.null 评论的那样。
嗯,事实证明它很晦涩。我们发现 CellPainting
事件持续 运行,每秒数十次。
事实证明,CellPainting
事件触发了 CellFormatting
事件,其中一些基础 DataRow
值被更改。显然这个 re-triggers 是 CellPainting
事件,因此循环。
更改代码以仅在与现有值不同时更新基础行值,防止循环,从而停止连续重绘。
进行此更改后,ContextMenuStrip 行为恢复正常,打开的窗体也正常绘制其控件。
没有解释的是为什么在我们从 .NET 3.5 迁移之前没有这个问题。我只能假设框架之间存在一些奇怪的差异,因为有问题的代码非常古老并且几年没有改变。
我们刚刚将我们的 VS2019 开发环境迁移到一个大型(~700 kloc)遗留 Windows Forms 应用程序,从 .NET 3.5 到 .NET 4.7.2,并因一个 windows 表格,出现了两个非常奇怪的问题:
- A
ContextMenuStrip
编码为在DataGridView
中的单元格中右键单击时出现,鼠标悬停时不会自动打开其子菜单(如果存在)- 需要单击。表面上编码相同的 ContextMenuStrip 在其他表单上表现正常。 - 从有问题的表单(来自所述 ContextMenuStrip)打开另一个表单,导致该表单上的控件未被绘制。如果激活另一个表单,然后重新激活打开的表单,则会出现控件。但是,以与其他表单完全相同的方式打开相同的表单会产生预期的行为。
我知道这里没有什么可继续的 - 我猜我们已经被 .net 3.5 和 4.7.2 之间的一些模糊变化绊倒了,但是 Google 博士没有透露任何线索到目前为止。
为了隔离问题而撕掉一些东西将非常困难 - 我们有各种继承的控件和自定义网格绘画,其中大部分是功能的关键。我没有尝试构建测试用例,因为相同的继承控件(使用 DataGridView 和 ContextMenuStrip)在同一应用程序的其他地方完美工作,创建测试表单似乎不会做任何事情,除了工作正常。
所以在这个阶段,如果能知道去哪里看,我将不胜感激。
环境:Visual Studio 2019 v16.11.10,.net 4.7.2,Windows Forms 应用程序,主要使用 VB.NET 编写,在某些 class 中使用了少量 C#图书馆。
我尝试过的事情:
- 大量谷歌搜索 .net 3.5 和 .net 4.7.2 之间的重大更改
- 注释掉 DataGridView 中的一些自定义绘画
- 在
x64
、x86
和AnyCpu
平台之间切换 - 编译 .NET 4.8 而不是 4.7.2 - 行为没有区别。
...都无济于事。
非常感谢收到任何想法。我会根据任何建议的结果更新问题。
编辑:
- 更正了对 ToolStripMenu 的引用 - 应该是 ContextMenuStrip,正如@dr.null 评论的那样。
- 添加了另一个测试:针对 .NET 4.8 进行编译和 运行,正如@dr.null 评论的那样。
嗯,事实证明它很晦涩。我们发现 CellPainting
事件持续 运行,每秒数十次。
事实证明,CellPainting
事件触发了 CellFormatting
事件,其中一些基础 DataRow
值被更改。显然这个 re-triggers 是 CellPainting
事件,因此循环。
更改代码以仅在与现有值不同时更新基础行值,防止循环,从而停止连续重绘。
进行此更改后,ContextMenuStrip 行为恢复正常,打开的窗体也正常绘制其控件。
没有解释的是为什么在我们从 .NET 3.5 迁移之前没有这个问题。我只能假设框架之间存在一些奇怪的差异,因为有问题的代码非常古老并且几年没有改变。