为什么在WinForm中隐藏控件比显示控件需要更长的时间?

4
我有一个包含56个复选框的FlowLayoutPanel。这些复选框用于三态模式。现在来说说有趣的部分。如果复选框未被选中,那么它们就没有使用,可以隐藏以便阅读。为了隐藏它们,我使用另一个复选框。当用户点击该复选框时,使用foreach迭代隐藏FlowPanel中所有未使用的复选框。
问题是,要隐藏它们,foreach调用(checkBox.Visible=false)需要约2-3秒钟,而显示它们(checkBox.Visible=true)只需要0.5秒钟。
有什么建议吗?为什么会出现这种情况?
private void hideUnusedPinsCheckBoxClick(objest sender, EventArgs e)
{
   bool state = !hideUnusedPinsCheckBox.Checked;
   foreach(object obj in flowLayoutPanel.Controls)
   {
      CheckBox cB = (CheckBox)obj;
      if(cB.CheckState == CheckState.Unchecked)
         cB.Visible=state;
   }
}

只是一个“元建议”:获取您选择的性能分析器(例如ANTS Performance Profiler),并测量哪些操作需要很长时间。 - Uwe Keim
我知道将它们隐藏起来比让它们可见需要更长的时间。 - Robert Iagar
2
你尝试过在 flowLayoutPanel 上使用 SuspendLayoutResumeLayout 函数包装循环吗? - Damien_The_Unbeliever
@RobertIagar 是的,这就是你在问题标题中已经陈述的内容。我的建议是帮助你找出“为什么”。 - Uwe Keim
@Damien_The_Unbeliever 那确实可以工作,但这不是问题的答案。 - Robert Iagar
2个回答

4
您可以在隐藏所有复选框之前尝试调用 SuspendLayout,然后在之后调用 ResumeLayout。有关详细信息,请参见此链接
至于您的问题“为什么”会发生这种情况。每次在FlowLayoutPanel上隐藏(或显示)控件时,都会执行面板布局算法以重新排列屏幕上的所有内容。例如,如果您连续隐藏50个复选框,则布局算法将执行至少1,275次。
- Hide checkbox
- Perform layout for remaining 49 check boxes
- Hide checkbox
- Perform layout for remaining 48 check boxes
- Hide checkbox
- Perform layout for remaining 47 check boxes
- etc...

通过调用SuspendLayout,布局算法在您调用ResumeLayout之前根本不运行,将次数从1,275减少到1。


看,我把这个作为评论发布了,因为它实际上并没有回答所提出的问题... - Damien_The_Unbeliever
@Damien_The_Unbeliever 对不起,我刚才没看到。我重新选了一个答案回答了问题。谢谢你的帮助。 - Robert Iagar
@RobertIagar 我已经修改了答案,解释了为什么它运行缓慢。 - MattDavey

3

如果您隐藏了某些内容,系统必须找出该对象下方的内容,并强制该内容重新绘制。

另一方面,当您使控件可见时,只有该控件需要被绘制。


这意味着如果我反过来做(从底层开始),那会更好吗? - Robert Iagar
不确定的话,最好先尝试MattDavey提出的“SuspendLayout”-“ResumeLayout”方法。 - Erich Kitzmueller
1
这回答了问题。解决方法是使用 SuspendLayout - ResumeLayout 方法。 - Robert Iagar
1
这不是问题的原因,问题的原因是布局算法运行了数百次 - 这就是为什么 SuspendLayout 修复了该问题。如果重绘是原因,SuspendLayout 将没有任何作用(SuspendLayout 无法阻止控件重新绘制)。 - MattDavey

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