c# - 系统特定的 ListView 列宽更改行为
问题描述
背景:今天早些时候,我在 github 上发布了一个用 C# .NET 和 WinForms 编写的开源应用程序。最初下载它的几个人发现它在启动时立即崩溃。假设我以某种方式搞砸了分发,我在这里发布了一个问题。一些乐于助人的人下载了该项目并很快确定问题是由堆栈溢出引起的。
所以这已经解决了,但问题仍然存在:为什么我运行这段代码时不会崩溃?
特定问题是由每当窗口或另一列的大小发生更改时尝试调整详细信息模式 ListView 的最右边列的代码引起的。事件处理程序正在设置列的ColumnWidthChanged
宽度,导致无限递归。
在我的系统上,它工作得很好(这里是视频)。一种可能的解释是我有一个特殊版本的 WinForms(或底层控件),如果列宽没有改变,它不会发布事件更改通知。
我真正想要的是高度确信在我的系统上运行的代码将在其他地方运行。回答我问题的人似乎很容易在他们的开发系统上重现崩溃。我是否设法安装了某种“防弹版”?
应用程序和库项目面向 .NET Framework 4.6.1 或 .NET Standard 2.0。将应用程序更改为目标 4.7.1 无效。我在 Windows 10 Pro 系统上使用 Visual Studio Community 2017,更新至 15.8.3。这是我第一次尝试桌面 C# .NET 应用程序,所以我可能在做一些愚蠢的事情。
更新:受到@jwdonahue 评论的启发,我进行了一个实验:在事件处理程序中,抓取 aStackTrace
并检查FrameCount
,记录看到的最大值。启用其中一个列更新后,我始终看到最大帧数为 414,并且ColumnWidthChanged
存在多个事件处理程序实例。如果我注释掉列更新,最大计数下降到 174,我只看到一个事件实例。
@LexLi 转发的失败运行的堆栈跟踪有 5087 个条目,所以这不是我的堆栈限制更高的简单问题。
解决方案
可能是在您的系统上,它最终会将列宽设置为现有值。如果新值与当前值相同,则可能不会触发更改的事件。
可能的原因有:
- 由于 DPI 不同,启动窗口大小可能会有所不同。
- 数据可能不同,导致不同系统上的宽度不同。
- 在失败的系统上,宽度可能不会收敛,而是在两个值之间交替。
- 从理论上讲,它可能取决于 .net 框架或操作系统的版本。
无论哪种方式,从实际的角度来看,最好将您的软件设计为没有循环计算。
推荐阅读
- html - 无论 confirm() 值如何,Typescript 条件代码都在运行
- gitlab - 如何在 Gitlab 中为特定域设置“用户上限”
- botframework - 团队机器人框架 - composeExtensions 不显示自适应卡上的按钮
- php - 如何将当前的 Bootstrap 卡片视图显示更改为 Bootstrap Carousel?
- python - Python - 从文本文件中读取行,更新行的子字符串并写入新的文本文件
- amazon-web-services - Sagemaker Notebook ml.g4dn.xlarge 实例不列出 GPU 设备
- flutter - 如何调整 pub 包“flutter_native_splash”中的图像大小?
- python - 如何。通过两个多处理调用使程序的内存效率更高?
- javascript - React 函数被多次调用(每秒)
- python - 连接两个应该是一个的 DataFrame