c# - 将控件添加到 TableLayoutPanel 的快速方法

标签 c# .net winforms tablelayoutpanel

我必须向 TableLayoutPanel 添加很多 Control 对象动态地,需要花费大量时间。我还需要能够通过 TableLayoutPanel 的行索引和列索引访问控件,反之亦然。

TableLayoutPanel.Controls(据我所知)有 3 种添加 Control 对象的方法:

  • .Add(Control) - 继承,位置为-1,-1 with .GetCellPosition(Control)
  • .Add(Control, column, row) - 位置和索引正确,但可能有点慢?
  • .AddRange (Control[]) - 继承的、更快的、显示的位置是正确的(每个单元格都已填充,如果需要,随后设置列跨度),但位置是 -1、-1 和 .GetCellPosition(控件)

有没有办法结合.Add(Control, column, row.AddRange(Control[])的优点,即添加很多Control 对象快速到 TableLayoutPanel,同时仍然能够以编程方式获取 Control 的位置?


编辑以包含评论中的一些信息:

  • 最多添加了 1000 个控件
  • 我已经使用了 SuspendLayout()ResumeLayout()
  • TableLayoutPanel 加载大约需要 2 秒。根据探查器,大约 50% 的时间用于添加控件,20% 用于 ResumeLayout()

编辑:MCVE
我的原始代码更复杂,但这是一个 TableLayoutPanel 示例,其中添加控件花费了大部分时间 (2/3)。我正在寻找一种方法来加快速度。

public class FormTLPTest : Form
{
    public FormTLPTest()
    {
        Height = 800;
        Width = 800;

        TableLayoutPanel tlp = new TableLayoutPanel();
        tlp.Dock = DockStyle.Fill;
        tlp.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
        tlp.AutoScroll = true;

        Controls.Add(tlp);

        tlp.ColumnCount = 7;
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100.0F));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 80));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 30));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20));

        tlp.SuspendLayout();

        for (int i = 0; i<700; i++)
        {
            Button btn1 = new Button();
            Label lb2 = new Label();
            Label lb3 = new Label();
            Label lb4 = new Label();
            TextBox tb5 = new TextBox();
            Button btn6 = new Button();
            Button btn7 = new Button();

            foreach (Control c in new Control[] { btn1, lb2, lb3, lb4, tb5, btn6, btn7})
            {
                c.Margin = new Padding();
                c.Dock = DockStyle.Fill;
                c.BackColor = Color.White;
            }

            btn1.FlatStyle = FlatStyle.Flat;
            btn6.FlatStyle = FlatStyle.Flat;
            btn7.FlatStyle = FlatStyle.Flat;

            btn1.Text = "1";
            lb2.Text = "Some longer Text - it contains information. Don't know what I should write to fill the space";
            lb3.Text = "Short Text";
            lb4.Text = "Short Text";
            tb5.Text = "5";
            btn6.Text = "Button";
            btn7.Text = "+";

            tlp.Controls.Add(btn1, 0, i);
            tlp.Controls.Add(lb2, 1, i);
            tlp.Controls.Add(lb3, 2, i);
            tlp.Controls.Add(lb4, 3, i);
            tlp.Controls.Add(tb5, 4, i);
            tlp.Controls.Add(btn6, 5, i);
            tlp.Controls.Add(btn7,6, i);
        }

        tlp.ResumeLayout();
    }
}

最佳答案

查看 Reference Source ,你可以看到 Control.ControlCollection.AddRange 方法只不过是一个包含在 SuspendLayout/ResumeLayout 中的 Add 循环>。由于您的代码也包含在此类调用中,因此性能应该没有差异。

TableLayoutPanel 做了两个额外的调用 - SetRowSetColumn ,所以我的第一个想法是它们是缓慢的部分。然而,查看源代码(并测量有或没有这些调用的时间),当布局引擎暂停时,它们对性能的影响可以忽略不计。

我通过完全不使用 TableLayoutPanel 而只是向表单本身添加控件,对您的 mcve 进行了一些额外的测试。结论是——你的控件太多了。 mcve 正在创建 4900 个控件。这对于 WinForms(以及一般的 Windows)来说太多了。运行它之后,我的 Windows 几乎死机了。

所以,添加控件的性能无法提升。但这不应该是您主要关心的问题。考虑切换到 DataGridView 或某些支持更多行的第三方数据转发器控件,而无需创建大量控件。

关于c# - 将控件添加到 TableLayoutPanel 的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36351347/

相关文章:

c# - Winforms 事件架构

c# - 如何从网络控制 C# 程序?也许使用 AJAX?

c# - 通过接口(interface)返回具体的仓库

c# - 头孢夏普 winforms : Inject jquery into page

c# - 使用Vim作为C#编辑器,面临一些问题

c# - BackgroundWorker 问题(C# Windows 窗体)

c# - 使用查询或代码

asp.net - 加密票证参数的值无效

c# - UnobtrusiveJavaScriptEnabled Spark View 引擎

c# - 在 C# 中创建可供选择的方法列表并获取它们的参数数量