SuspendLayout/ResumeLayout是无用的吗?还是我的使用方式有误?

6
我有两个选项卡页面,它们承载动态填充的标签和文本框的TableLayoutPanel。第一个页面有96个标签和96个文本框,尽管有些闪烁但还可以接受,因此我没有添加SuspendLayout/ResumeLayout对。
然而,第二个页面有96个标签和288个文本框,其绘制/闪烁是无法容忍的。也就是说,192个控件看起来还好,但384个明显不行。
我在动态创建控件之前调用了SuspendLayout方法,然后在finally块中调用了ResumeLayout方法,但我将它们移除了,结果很神奇!与第一个选项卡页面/TLP一样,闪烁是可以接受的。
那么,为什么减少代码反而有效呢?

SuspendLayoutControl 类的一个方法。你在调用哪个 Control 上的它? - Robert Harvey
好的提示;我之前是在“this”(窗体)上调用它。所以,我尝试在tabPage和TableLayoutPanel上都调用它。这似乎并没有比注释掉对this.SuspendLayout()和this.ResumeLayout()的调用更好或更差。 - B. Clay Shannon-B. Crow Raven
1
请查看https://dev59.com/ZHA65IYBdhLWcg3wogEb。 - Robert Harvey
我之前使用过Passant的那段代码,它非常好用,但是有关方面不想使用它,认为它太过深奥。 - B. Clay Shannon-B. Crow Raven
1
我已经使用ScrollToCaret()测试了SuspendLayout(),它会产生闪烁并且不能暂停布局。如果您的布局涉及移动滚动条位置,则此方法调用实际上不会暂停屏幕更新。 - Dan
显示剩余3条评论
2个回答

10

您也可以尝试本主题中我列出的两种方法。希望它们不会太深奥:

https://dev59.com/b2vXa4cB1Zd3GeqPLq0V#15020157

这些方法确实暂停并恢复了布局。但您不应忘记调用EndControlUpdate()

我在创建任何通用控件时都会使用此方法。我尝试过很多次使用暂停和恢复布局来对齐控件,但从未按照我预期的方式工作。


2

一开始,我也有同样的疑惑,即 SuspendLayoutResumeLayout 是否真的有效。之后我自己尝试了一下,创建了一个示例应用程序,并更深入地了解了这个概念。

所以,这是我做的:

mainPanel.SuspendLayout()

create child control

call child.SuspendLayout()

change the child control properties

add the child control to the mainPanel

call child.ResumeLayout(false) - this means: next layout run, relayout this control, but not immediately

repeat (2-6) for every child-control

call mainPanel.ResumeLayout(true) - this means: relayout my mainPanel and every child-control now!

此外,为了证明我的想法,这里提供一个示例应用程序。
Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        this.SuspendLayout();
        for (int i = 0; i < 2000; i++)
        {
            var textbox = new TextBox();
            //textbox.SuspendLayout();
            //textbox.Dock = i% 2 ==0 ? DockStyle.Left : DockStyle.Right;
            textbox.Dock = DockStyle.Fill;
            textbox.Top = i * 10;
            textbox.Text = i.ToString();
            this.Controls.Add(textbox);
            //textbox.ResumeLayout(false);

        }
        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",ts.Hours, ts.Minutes, ts.Seconds,ts.Milliseconds / 10);

        this.ResumeLayout(true);
        MessageBox.Show(elapsedTime);

不要忘记注释掉这个.SuspendLayout()和this.ResumeLayout(True)。 - Sandip

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