【问题标题】:Why is adding SuspendLayout and ResumeLayout reducing performance?为什么添加 SuspendLayout 和 ResumeLayout 会降低性能?
【发布时间】:2012-10-29 13:54:20
【问题描述】:

我需要给一个父控件添加很多控件。

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

所以SuspendLayoutResumeLayout 不应该减少添加子控件的时间,对吧?那么使用SuspendLayoutResumeLayout 有什么好处,或者换句话说,如果我不使用SuspendLayoutResumeLayout 而是直接将子控件添加到父母,有什么不好的?

【问题讨论】:

  • 您要添加多少控件?如果只是几个,则没有必要,但是如果您要添加数百/数千个,则更有可能看到差异。另外,如果您计时,两次之间的区别是什么?它只是很小的一部分(足以只是执行时间的随机变化)还是真的很重要?
  • 您使用的是哪些类型的控件? here 描述了类似的问题。
  • 是的,我添加了数百个控件。
  • 我认为您需要显示两个版本的代码,以便尝试真正的答案
  • 没有代码很难确定。我使用相同的方法,在 SuspendLayout 时非常快速地添加数百个动态控件而没有问题

标签: c# winforms layout controls suspend


【解决方案1】:

您可能想改用 .ResumeLayout(false)。调用 mySubPanel.ResumeLayout() 等于 .ResumeLayout(true),这意味着它应该立即重新布局该控件(以及此时未暂停的所有子控件)。

MSDN 引用:“如果有任何挂起的布局请求,调用 ResumeLayout 方法 [不带参数] 会强制立即布局。” [1]

如果您想在一个面板中添加 100 个控件,您希望使用这样的方法:

  1. mainPanel.SuspendLayout()
  2. 创建子控件
  3. 调用 child.SuspendLayout()
  4. 更改子控件属性
  5. 将子控件添加到主面板
  6. 调用 child.ResumeLayout(false) - 这意味着:下一次布局运行,重新布局此控件,但不是立即
  7. 对每个子控件重复 (2-6)
  8. 调用 mainPanel.ResumeLayout(true) - 这意味着:现在重新布局我的 mainPanel 和每个子控件!

注意:如果没有 SuspendLayout(),控件的每个属性更改都会调用布局例程 - 即使更改 .BackColor 也会使您的控件重新布局本身。

[1]http://msdn.microsoft.com/en-us/library/y53zat12.aspx

【讨论】:

  • 如果我们正在迭代(循环)很多控件来进行属性更改,这尤其有用。对循环情况有很大的影响。谢谢!
【解决方案2】:

这是出于通常的原因,删除代码通常会使您的程序运行得更快。

Suspend/ResumeLayout() 被普遍误解。只有当您拥有具有非默认 AutoSize、Dock 或 Anchor 属性的控件时,它才会生效。当控件具有相互影响的布局属性时,它可以防止布局事故。

如果您有一个包含 数百个 控件的表单,那么您根本不可能使用这些属性。这么大的窗口不容易自动布局。所以你调用的方法实际上并没有做任何事情,它们需要时间来迭代布局但没有任何好处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 2010-10-27
    • 2017-07-07
    • 2012-01-18
    相关资源
    最近更新 更多