I have to add a lot of Control
objects to a TableLayoutPanel
dynamically, what takes a significant amount of time. I also need to be able to access the controls via row- and column-index of the TableLayoutPanel
and vice versa.
TableLayoutPanel.Controls
has (as far as I know) 3 ways to add Control
objects:
.Add(Control)
- inherited, position is -1,-1 with .GetCellPosition(Control)
.Add(Control, column, row)
- position and indexes are correct, but maybe a bit slow? .AddRange (Control[])
- inherited, faster, shown position is correct (every cell is filled, if necessary columnspans are set afterwards), but position is -1,-1 with .GetCellPosition(Control)
Is there a way to combine the advantages of .Add(Control, column, row
and .AddRange(Control[])
, ie to add a lot of Control
objects fast to a TableLayoutPanel
while still being able to get the position of a Control
programmatically?
EDIT to include some information from the comments:
SuspendLayout()
and ResumeLayout()
TableLayoutPanel
takes about 2 seconds to load. According to the profiler roughly 50% of the time is spent with adding Controls, 20% with ResumeLayout()
EDIT: MCVE
My original code is more complex, but this is an example of a TableLayoutPanel
where adding the controls takes most of the time spent (2/3). I am searching for a way to speed this up.
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();
}
}
Looking at the Reference Source , you can see that Control.ControlCollection.AddRange
method is nothing more than a Add
loop enclosed in SuspendLayout
/ ResumeLayout
. Since your code is also enclosed with such calls, there should not be a difference in the performance.
TableLayoutPanel
does two additional calls - SetRow and SetColumn , so my first thought was that they are the slow parts. However, looking at the the source code (and measuring the time with or w/o those calls), when the layout engine is suspended, their affect on the performance are negligible.
I did some additional tests with your mcve
by not using TableLayoutPanel
at all and just adding controls to the form itself. The conclusion is - you just have too many controls. mcve
is creating 4900 controls. This is too much for WinForms (and Windows in general). After running it, my Windows almost died.
So, the add control performance cannot be improved. But that should not be your main concern. Consider switching to DataGridView
or some third party data repeater control which support a lot more number of rows w/o creating significant number of controls.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.