Dynamically creating TextBoxes
hi,
I have a simple program. I got row and column number from the user and create a row*column matrix of TextBoxes. For examle; when the user set row number to 3 and column number to 2. Then i got;
* *
* *
* *
(the stars are textboxes). Of course i am creating those textboxes dynamically.
I am using the code below to create textboxes; (MyTextBox is a class derived from TextBox class)
MyTextBox [,] boxes = new MyTextBox[row,column];
this.SuspendLayout();
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
boxes[i, j] = new MyTextBox(xcoor, ycoor);
this.Controls.Add(boxes[i, j]);
xcoor += 50;
}
ycoor += 30;
xcoor = 180;
}
this.ResumeLayout(false);
xcoor and ycoor is about coordinates(not important). I am using array because i will get the integers in those textboxes to a integer array soon. My question is: Is this a good code? :) I am asking this because when the user enters 100 and 100 to row number and column number program gets slower and creation of textboxes takes some seconds.
Can you advise a better solution?
[1197 byte] By [
hkullana] at [2007-11-20 9:52:12]

# 1 Re: Dynamically creating TextBoxes
The problem is not the creation of the textbox controls, but the drawing of them. Your code is good.
You can test this by adding 100 textbox controls (or even labels) to a form. The drawing will take very long, and you will see all controls drawing one by one.
I have been wrestling a lot with "performance problem", and it seems that when you add a lot of controls to a user control, the drawing speeds up a lot (I guess because all user controls draw themself so the mainform doesn't have to do the drawing for these controls). But in your case, it's quite difficult to use user controls (or you must predefine some basic values (such as 5 x 5 or 10 x 10) and fill the other textboxes with single values. This will speed up your application a lot (but will make it more difficult to implement)!
# 2 Re: Dynamically creating TextBoxes
Thank you very much to you interest and help but i am sorry that i cannot understand what you want to say.
"and it seems that when you add a lot of controls to a user control, the drawing speeds up a lot (I guess because all user controls draw themself so the mainform doesn't have to do the drawing for these controls)."
what did you want to say in here.
# 3 Re: Dynamically creating TextBoxes
That when you have a lot of controls in the Forms.Controls array, the drawing of all the controls takes a long time (it's not the creation of the textbox that takes a long time, it's the drawing of the controls).
I just tried to write a small example of this, but it seems my computer is too fast (before this, I worked on a laptop which was having a lot of difficulties to draw a complex form). As soon as I moved the parts of the form into user controls, the form speeded up.
What you can do is measure the time of the function calls. For example, how long does the complete for-loop take? And how long does the function ResumeLayout(false); take? I think the ResumeLayout takes longer than the real creation of the controls.
# 4 Re: Dynamically creating TextBoxes
yea i understand but when i remove the resumelayout and suspendlayout methods the drawing of the textboxes become much more slower. I cannot understand your advise.
"As soon as I moved the parts of the form into user controls, the form speeded up."
what should i do? thanks for help
# 5 Re: Dynamically creating TextBoxes
Indeed it takes much longer. So, what I am trying to say is, the drawing of all the textboxes is the function that is taking long, not the actual creation of the textboxes.
What I experiences in the past (but it seems I can't reproduce the error now) is that when you have a lot of controls in one form, the updating is very slow. When I added groups of controls into a user control (you know what a user control is, right?) and added these user controls to the form, the form speeded up a lot (no drawing issues any longer).
So what I am trying to say is (choose one of the items below):
1) Don't display so many textboxes (but I guess you already thought about UI design so this it's probably a requirement to display so many textboxes).
2) Try to group textboxes together into a user control and add these to the form. This might speed up the progress of drawing all the textboxes.
3) Create a custom control for which you can set the columns and rows, and only display the data that should be displayed (which on a normal resolution will give you at most 30 rows and 10 columns?). This is more work, but then you have full control about the rows and columns that are currently being drawn.
# 6 Re: Dynamically creating TextBoxes
I am using array because i will get the integers in those textboxes to a integer array soon.
That when you have a lot of controls in the Forms.Controls array...
I think we're talking about the Controls Collection right
I came accross this very very interesting article (http://msdn.microsoft.com/msdnmag/issues/06/03/WindowsFormsPerformance/default.aspx) about Apllication performance. Let me quote :
Changes such as resizing or realigning a control can also cause problems. For example, when child controls are added to a form or ToolStrip, a Control.Layout event is fired. A change to the size or location of a child control will cause a Layout event on a parent control. Font size changes will also cause a Layout event. In response to the Layout event, the form scales and arranges controls. Having too many Layout events processed while you create or resize your control may have a significant performance impact.
Component code generated by the Windows Forms designer starts with SuspendLayout and ends with ResumeLayout. This is done to avoid performing layout on the form while it is being created and populated with controls. The SuspendLayout method allows multiple actions to be performed on a control without generating a Layout event for each change. Use this technique whenever possible to minimize the number of Layout events.
Remember that SuspendLayout only prevents Layout events from being performed for that particular control. If controls are added to a panel, for example, SuspendLayout and ResumeLayout must be called for the panel and not for the parent form.
Changing properties such as Bounds, Size, Location, Visible, and Text for AutoSize controls will fire a Layout event. It will be even more expensive if these properties are changed in Form.Load, since all handles are created by then and thus many messages will be processed. This is another place where you should add SuspendLayout and ResumeLayout to prevent extra Layout events from occurring. If possible, make all of these changes within InitializeComponentthis way only one Layout event is ever needed.
Several properties dictate the size or location of a control: Width, Height, Top, Bottom, Left, Right, Size, Location, and Bounds. Setting panel1.Width and then panel1.Height causes twice the work of setting them both together via panel1.Size.
If the handles are created you will notice the difference, even if you use SuspendLayout and ResumeLayout calls. SuspendLayout only prevents Windows Forms OnLayout from being called. It will not prevent messages about size changes from being sent and processed. You should try to set the property that reflects the most information you have. If you're just changing the size, set Size; if you're changing the size and location, change Bounds.
That should hopefully clear up the confusion with SuspendLayout & ResumeLayout
# 7 Re: Dynamically creating TextBoxes
Well, he is already using SuspendLayout and ResumeLayout, so I guess this will not improve any performance.
I think hkullana should (re-)consider his design about showing so many textboxes at once (or at least loading so many textboxes at once).
# 8 Re: Dynamically creating TextBoxes
I agree in that sense with you. I was thinking, perhaps he should not depend on the form only for the creation of controls. I've found, that by having a separate class (which creates the Textbox ), and of course exposes all the necessary properties & methods, does indeed allow the creation of dynamic textboxes ( or any control ) to become faster.