我正在尝试将所有控件从动态表单复制到另一个静态声明的表单。奇怪的是,其中一半正在被复制。代码看起来像这样 -
// 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);
}
对于一个特定的例子,在循环开始时有56个控件,并且在循环完成时仍有27个控件。只是为了测试我在第一个之后再次添加相同的for循环。这次还有13人。
为什么只有一半的控件被添加?为什么foreach
循环过早退出?
PS :我之所以这样做是因为我知道一种捕捉动态表单击键的方法。对于静态表单,我可以覆盖ProcessCmdKey
并捕获键击,但我不知道动态表单的任何等价物
答案 0 :(得分:1)
您的假设可能就是:
foreach (Control c in form.Controls)
{
this.Controls.Add(c);
}
仅影响一个ControlColection,即this
上的集合。但是,控件只能有一个父级。 Add
实现的内部结构揭示了以下内容:
public virtual void Add(Control value)
{
// skipped stuff
if (value.parent != null)
{
value.parent.Controls.Remove(value);
}
base.InnerList.Add(value);
// many more
}
注意Add
方法如何为父控件集合调用Remove
。 InnerList
是ArrayList
。每次将控件添加到另一个表单时,它的大小都会减少。因此,你只处理了其中的一半。
首先将控件副本添加到List<Control>
之前,然后将列表中的控件添加到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);