Foreach 在将它们从一种形式复制到另一种形式时不遍历所有控件
Foreach not looping through all controls while copying them from one form to another
我正在尝试将所有控件从动态窗体复制到另一个静态声明的窗体。奇怪的是,其中恰好有一半被复制了。代码看起来像这样-
// 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
并捕获击键,但我不知道动态表单有任何等效项
您的假设可能是:
foreach (Control c in form.Controls)
{
this.Controls.Add(c);
}
只影响一个 ControlCollection,即 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);
我正在尝试将所有控件从动态窗体复制到另一个静态声明的窗体。奇怪的是,其中恰好有一半被复制了。代码看起来像这样-
// 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
并捕获击键,但我不知道动态表单有任何等效项
您的假设可能是:
foreach (Control c in form.Controls)
{
this.Controls.Add(c);
}
只影响一个 ControlCollection,即 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);