【问题标题】:How to avoid a large number of user controls on a form如何避免表单上有大量用户控件
【发布时间】:2011-06-15 14:06:40
【问题描述】:

我正在创建一个代表其他自定义控件列表的用户控件(它们非常简单:包括标签、复选框、图标和按钮)。当我将它放在表单上时,加载所有列表项需要很长时间(列表中有 100 - 150 个项目)。显示大量自定义控件列表的替代方法是什么?

我尝试使用 SuspendLayout 和 ResumeLayout 但没有多大帮助,使用它们减少了时间,但仍然太长了。

有一些想法由于各种原因我无法实现:

  • 以某种方式只处理落入视图中的项目(如何忽略其他项目?)
  • 实现 Grid 控件行为 - 仅在编辑模式下创建自定义控件,但很难绘制其他控件

感谢任何建议

编辑:

有一些使用 DataGridView 的建议。这是个好主意,但问题是自定义控件可以更改它的大小并在下面显示附加信息(它的行为类似于扩展器)。用DataGridView做起来不容易

【问题讨论】:

  • 创建一个不需要同时在屏幕上显示大量控件的 UI 设计? :D
  • @ShaneC 我愿意!但是我被要求在屏幕上显示 100-150 个项目,我别无选择,只能为每个项目创建一个自定义控件。我应该使用分页吗?我在winforms里没见过
  • 听起来像一个神形式。您可能想改用多种形式。科学证明,表单上的控件过多会使用户的大脑融化。
  • SuspendLayoutResumeLayout 有一些可衡量的效果这一事实使我认为您在 构造函数 之外的其他地方编写了布局代码,例如 @987654323 @事件处理方法?始终将初始化代码放在构造函数中,这样 Windows 就不必根据您设置的属性多次(重新)创建控件。
  • @Cody Gray 问题是我正在获取有关创建表单后这些项目应该是什么的必要信息。

标签: c# winforms performance user-controls


【解决方案1】:

如果您使用 WinForms,那么我强烈建议您改用 DataGridView。不久前我遇到了同样的问题,发现 DataGridView 的可扩展性足以列出各种控件(TextBoxes、CheckBoxes,甚至 DateTimePickers 等)。转换到此控件极大地加快了我的 UI,并且更稳定且更易于维护。

如果您在每一行都需要更高级的功能,例如您提到的 Expander 属性,那么我认为您应该研究 WPF。使用 WPF,您可以灵活地按照您想要的方式完全设计您的 UI 控件,并且性能仍然非常好。

如果这些都不适合您,那么重新设计您的 UI 怎么样?如前所述,没有办法减轻大量控件对性能的影响。那么如何一次显示一行或几行,使用过滤器或搜索工具让用户找到他们想要的行。或者,显示所有行但只在每行中使用最少的控件,并让用户双击该行以调出一个对话框窗口以显示有关该行的更多详细信息?您必须以某种方式减少最初显示的控件数量。这些只是一些想法。

【讨论】:

  • 这是一个非常好的主意,但是有一个问题。我会更新我的问题
  • @Sorin Comanescu VirtualMode 暗示我将手动绘制其他所有内容。这就是我描述为无法实现的第二个想法的问题
【解决方案2】:

我同意@Cody 的观点,但是,如果无法选择“剥离一些你所拥有的”……让我更进一步……

你提到你有一个清单。

我会从 iOS 剧本中得到一个提示,并且只有您需要在屏幕上显示列表的活动控件数量。

例如;如果列表在屏幕上有 30 个项目的空间,您可以在用户滚动/翻阅列表时重复使用相同的 30 个控件。

这带来了另一点 - 有时稍微修改导航是一个不错的选择。如果您现在有一个巨大的列表,那么可能需要考虑一个“分页”功能,即每个“页面”只显示 x 个项目。

无论如何,当您在应用程序中达到这一点时,并且您对现实世界的加载速度/内存使用性能有要求,是时候破解关于性能调优的旧书,并实施经过验证的模式,如重用、缓存等。它通常并不总是很漂亮,而且它会使您的解决方案更加复杂,但您需要做一些事情才能使其正常工作。

【讨论】:

  • 嗯,(你的最后一段)实际上不太可能有帮助。 Windows 必须先创建所有这些控件,然后才能在屏幕上显示它们。这些控件中的每一个(有时还有这些控件的子控件)都代表一个本机“窗口”(是的,Windows 是由“窗口”组成的,这些程序员是多么聪明),而这并不不要免费来。即使是应用程序中性能最高的代码也不太可能在这里有所作为。通常的伎俩将被挫败。唯一的解决方案是尽量减少您创建的控件数量。期间。
  • @Cody;我完全不同意你的看法(或者,也许我们说的是同一件事)。重用现有控件(正如我在上一段中提到的)绝对会有所帮助,因为系统不必重新分配和重新创建相关的内存、窗口句柄等。
  • 是的,这就是为什么我澄清说我只是专门回应你的最后一段。重用现有控件绝对是正确的想法。
  • @Cody;最后几段说:“是时候破解关于性能调优的旧书了,并实施经过验证的模式,例如重用 [...]”
  • 我想我阅读的内容比你想要暗示的要多。翻阅关于性能调优的书让我想到了算法和 Donald Knuth,而不是重用窗口句柄。 ;-)
【解决方案3】:

不幸的是,没有办法不劳而获。生活中的事情不是免费的。如果表单上的控件数量不合理,则必须为加载它们所花费的时间付费。唯一的选择是使用更少的控件。

您是通过剥离一些已有的内容来实现这一点,还是通过自定义绘制内置对应项的更轻版本来实现这一点,这取决于您。但我强烈建议您坚持使用本机控件并放弃一些您现在正在使用的控件。

除了明显的性能问题外,您描述的场景肯定会产生用户溢出错误,这是任何调试器都无法修复的。

【讨论】:

    【解决方案4】:

    使用 DataGridView 并自定义列?

    【讨论】:

    • 这是一个选项,但我的自定义控件可以改变它的大小(本质上它是一个有标题并显示一些附加信息的扩展器)。当用户单击按钮时,它应该展开它的内容。在网格中做到这一点并不容易
    猜你喜欢
    • 2021-08-03
    • 1970-01-01
    • 2018-09-02
    • 2014-06-08
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多