Related to Controls.Add(childcontrol)

  • Thread starter Thread starter Brad Huff
  • Start date Start date
B

Brad Huff

A couple of days ago, I had posted an issue about a
program crashing when too many Controls.Add(childcontrol)
was performed. The code snippet below illustrates this
problem with a TextBox component:

using System;
using System.Windows.Forms;
using System.Drawing;

public class Test{

public class MyForm:Form{

Button button = new Button();
int count = 0;

public MyForm(): base() {
InitializeComponent();
}
private void InitializeComponent(){
//this.Width = 1000;
//this.Height = 900;
button.Click += new EventHandler(click);
button.Width = 300;
Controls.Add(button);
}

private void click(object sender,EventArgs e){
TextBox[,] controlSet = new TextBox
[1,5000];
Label label = new Label();
for (int i = 0;i<5000;i++){controlSet
[0,i] = new TextBox();}
count++;
button.Text = count.ToString();
Controls.Clear();
Controls.Add(button);
label.Location = new Point(0,50);
Controls.Add(label);
for (int i=0;i<5000;i++){
try {
controlSet[0,i].Location =
new Point(0,100); Controls.Add(controlSet[0,i]);
} catch (Exception ex)
{label.Text = ex.Message;}
}
}

public static void Main(string[] args)
{
MyForm form = new MyForm();
Application.Run(form);

}
}
}


When the button is pressed the 2nd time, after about 2
minutes, an error message states that a window handle
could not be found. I know that the situation above
maybe hypothetical but but it would be useful to explore
the limitation and or possibly a bug with Control class.
How would you change the snippet so that the button
clicks good. The example is for 5000 TextBox
components. If I use only 1000, the button could be
pressed many times without a problem, also goes much
quicker.

Thanks,

Brad
 
Hi Brad,
When the button is pressed the 2nd time, after about 2
minutes, an error message states that a window handle
could not be found. I know that the situation above
maybe hypothetical but but it would be useful to explore
the limitation and or possibly a bug with Control class.
How would you change the snippet so that the button
clicks good. The example is for 5000 TextBox
components. If I use only 1000, the button could be
pressed many times without a problem, also goes much

I didn't get any exception. I think your approach is wrong, though. How do
you expect a form to handle 5000 child componens to repaint them, etc. What
you should do is to use a grid control that will draw only the visible part
of the grid. The grid control probably should use only one control to edit
the selected grid cell.

HTH
B\rgds
100
 
Drawing only the visible controls has been tried. There
are additional problems with the scroll however. Also,
my mysterious error would still comes up. Did you run my
snippet as/is? I tested the snippet and ran it. I
wouldn't know why you didn't get any error with 5000
TextBoxes.

Brad
 
Yes, I tried almost as is. I copied only the click event for the button. I
don't think there is something special in the other methods. I click the
button three times. I had to wait couple of minutes between clicks for the
form to add controls to the collection. Then it was realy unresponsive. It
couldn't be different with 5000 children.
Actually when I moved the form it took really long time until the buttom
became visible again.
My suggestion is not to draw the visible controls only. I believe the best
is to have only two controls (In a real situation you may have more controls
dwpwnding of how many different types of data you have). The first would be
a grid control. The grid control would paint directly on its surface and
will repaint only the visible part of the control. The second would be an
edit control that will stay hidden unless the user selects cell (row) on the
grid for editing. In the latter case (when the user selects a cell) the edit
control will be initialized, positioned and shown accordingly.

B\rgds
100
 
If you still want to use 5000 child controls try to suppress the layout at
the begining of the click event handler (Control.SuspendLayout) and resume
the layout at the end (Control.ResumeLayout).

B\rgds
100
 
Back
Top