Reputation: 28535
I am trying to copy all controls from a dynamic form to another statically declared form. Curiously exactly half of them are getting copied. The code looks like this-
// Constructor of static form
public ApplicationForm(dynamic form)
{
// Add all controls from the dynamic form to the Application form
Console.WriteLine("I have total of {0} controls\n", form.Controls.Count);
int i = 0;
foreach (Control c in form.Controls)
{
i++;
this.Controls.Add(c);
Console.WriteLine(" Number of controls rem {1}\n",
form.Controls.Count);
}
Console.WriteLine("I added a total of {0} controls and still have {1}\n",i,
form.Controls.Count);
}
For one particular example, there were 56 controls at the beginning of the loop and there were 27 still remaining at the completion of the loop. And just to test I added the same for loop again after the first one. This time there were 13 remaining.
Why are only half of the controls getting added? Why is the foreach
loop exiting prematurely?
PS: I reason I am doing this copy is because I do know a way of capturing keystrokes for a dynamic form. For a static form, I can override ProcessCmdKey
and trap keystrokes but I dont know of any equivalent for dynamic forms
Upvotes: 1
Views: 445
Reputation: 42443
Your assumption probably is that this:
foreach (Control c in form.Controls)
{
this.Controls.Add(c);
}
only affects ONE ControlColection, namely the collection on this
. A control however can only have ONE parent. The internals of the Add
implementation reveals the following:
public virtual void Add(Control value)
{
// skipped stuff
if (value.parent != null)
{
value.parent.Controls.Remove(value);
}
base.InnerList.Add(value);
// many more
}
Notice how the Add
method calls Remove
for the parent controlcollection. The InnerList
is an ArrayList
. It's size gets reduced on the parent every time you add a control to the other form. Hence you only process half of them.
Before you start adding the Controls copy to a List<Control>
first and then add the controls from the list to the ApplicationForm.
// copy controls to list
var list = new List<Control>();
foreach (Control c in form.Controls)
{
list.Add(c);
}
Console.WriteLine("I have total of {0} controls\n", form.Controls.Count);
int i = 0;
// iterate over list
foreach (Control c in list)
{
i++;
this.Controls.Add(c);
Console.WriteLine(" Number of controls rem {1}\n",
form.Controls.Count);
}
Console.WriteLine("I added a total of {0} controls and still have {1}\n",i,
form.Controls.Count);
Upvotes: 2