为什么添加 SuspendLayout 和 ResumeLayout 会降低性能?

13

我需要向父控件添加很多控件。

但是,我发现如果我在将这些控件添加到父控件之前和之后使用ParentControl.SuspendLayoutParentControl.ResumeLayout,我用秒表来测量它: 如果我删除代码ParentControl.SuspendLayoutParentControl.ResumeLayout,速度会更快。这是为什么呢?

所以,SuspendLayoutResumeLayout并不应该减少添加子控件的时间,对吗?那么使用SuspendLayoutResumeLayout有什么好处呢?换句话说,如果我不使用SuspendLayout ResumeLayout而直接向父控件添加子控件,有什么坏处吗?


你要添加多少控件?如果只是几个,那就没必要了,但如果你要添加数百或数千个,你更可能会看到差异。另外,如果你计时了,两次之间的差异是多少;是一些微小的量(足以成为执行时间中的随机变化),还是真正显著的差异? - Servy
你使用哪些类型的控件?类似的问题在这里描述:http://www.clubfarpoint.com/Forums/forums/thread/32939.aspx。 - Victor Zakharov
是的,我添加了数百个控件。 - spspli
我认为你需要展示代码的两个版本,才能尝试给出一个真正的答案。 - Alan
很难确定没有代码。我使用相同的方法,在 SuspendLayout 的情况下快速添加数百个动态控件而不出现问题。 - Rached N.
我们调用“挂起”和“恢复布局”命令来避免在添加任何控件时触发事件。此外,如果不暂停控件,则有时会在添加控件时引起闪烁。 - Sandy
2个回答

19
您可能想使用的是 .ResumeLayout(false)。调用 mySubPanel.SuspendLayout() 相当于 .ResumeLayout(true),这意味着它应立即重新布局此控件(以及那时未被挂起的所有子控件)。
MSDN 引用:“如果存在任何待处理的布局请求,则调用 ResumeLayout 方法[不带参数]会强制立即进行布局。” [1]
如果您要向面板添加100个控件,您应该使用以下方法:
  1. mainPanel.SuspendLayout() 暂停主面板
  2. 创建子控件
  3. 调用 child.SuspendLayout() 暂停子控件的布局逻辑
  4. 更改子控件属性
  5. 将子控件添加到 mainPanel 中
  6. 调用 child.ResumeLayout(false) - 这意味着:下一次布局运行时,重新布局此控件,但不立即执行
  7. 重复执行 (2-6) 步骤,直到每个子控件完成布局
  8. 调用 mainPanel.ResumeLayout(true) - 这意味着:现在重新布局我的主面板和每个子控件!
注意:如果没有使用 SuspendLayout(),控件的每个属性更改都会调用布局程序--甚至更改.BackColor 也会使控件重新布局。
[1] http://msdn.microsoft.com/en-us/library/y53zat12.aspx

2
这对于我们遍历(循环)大量控件进行属性更改的情况特别有帮助。在循环情况下有很好的效果。谢谢! - rajkumaradass

10

通常情况下,删除代码可以使您的程序运行更快。

Suspend/ResumeLayout()被广泛误解。只有在控件具有非默认的AutoSize、Dock或Anchor属性时,它才会产生影响。 它可以防止布局属性相互影响而导致布局问题。

如果您有一个包含数百个控件的窗体,则很可能根本不会使用这些属性。这样一个庞大的窗口并不适合自动布局。因此,您调用的方法实际上没有任何作用,它们需要花费时间来迭代布局,但没有任何好处。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接