Foreach在将它们从一种形式复制到另一种形式时不循环遍历所有控件

时间:2015-10-17 09:12:52

标签: c# forms foreach controls

我正在尝试将所有控件从动态表单复制到另一个静态声明的表单。奇怪的是,其中一半正在被复制。代码看起来像这样 -

// 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并捕获键击,但我不知道动态表单的任何等价物

1 个答案:

答案 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方法如何为父控件集合调用RemoveInnerListArrayList。每次将控件添加到另一个表单时,它的大小都会减少。因此,你只处理了其中的一半。

首先将控件副本添加到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);