C# 将控件从一个面板复制到下一个面板时,为什么要删除控件

C# 将控件从一个面板复制到下一个面板时,为什么要删除控件,c#,controls,panels,C#,Controls,Panels,我创建了一个模板面板,以便在加载保存记录的表单时使用。当添加新记录时,我有一个方法复制模板面板,然后将其添加到每个记录的面板列表中。不知何故,当我复制模板面板时,控件被从模板面板中删除,我不知道这是如何发生的。下面列出了执行此操作的代码部分 Panel pn = new Panel() { Width = _PNTemp.Width, Height = _PNTemp.Height, Left = 0,

我创建了一个模板面板,以便在加载保存记录的表单时使用。当添加新记录时,我有一个方法复制模板面板,然后将其添加到每个记录的面板列表中。不知何故,当我复制模板面板时,控件被从模板面板中删除,我不知道这是如何发生的。下面列出了执行此操作的代码部分

Panel pn = new Panel()
        {
            Width = _PNTemp.Width,
            Height = _PNTemp.Height,
            Left = 0,
            Top = 0,
            BackColor = _PNTemp.BackColor,
            ForeColor = _PNTemp.ForeColor,
            AutoScroll = true,
            Name = _PNTemp.Name,
            Tag = _PrgPanels.Count.ToString()
        };

        MessageBox.Show(_PNTemp.Controls.Count.ToString());
        foreach (Control c in _PNTemp.Controls)
        {
            pn.Controls.Add(c);
            MessageBox.Show(_PNTemp.Controls.Count.ToString());
        }
        MessageBox.Show(_PNTemp.Controls.Count.ToString());
        _PrgPanels.Add(pn);

我将messagebox.show()放在3点处,以缩小它发生的位置。第一个显示控件的正确数量,第二个和第三个显示控件总数的1/2。为什么会这样?

一个控件一次只能在一个面板上。我在代码中添加了内联注释,以帮助解释发生了什么

Panel pn = new Panel()
    {
        Width = _PNTemp.Width,
        Height = _PNTemp.Height,
        Left = 0,
        Top = 0,
        BackColor = _PNTemp.BackColor,
        ForeColor = _PNTemp.ForeColor,
        AutoScroll = true,
        Name = _PNTemp.Name,
        Tag = _PrgPanels.Count.ToString()
    };

    MessageBox.Show(_PNTemp.Controls.Count.ToString());
    //all the controls are still inside _PNTemp
    foreach (Control c in _PNTemp.Controls)
    {
        pn.Controls.Add(c);
        MessageBox.Show(_PNTemp.Controls.Count.ToString());
        //Each time this runs you remove a control from _PNTemp to pn. 
    }

    //All the controls moved from _PnTemp to pn
    MessageBox.Show(_PNTemp.Controls.Count.ToString());
    _PrgPanels.Add(pn);

这是因为每个控件只能添加到一个父控件。模板面板中的所有控件都已是模板面板的子控件。尝试将这些控件添加到新面板时,这些控件将从模板面板中删除

根据:

一个控件一次只能分配给一个控件。ControlCollection 时间如果该控件已经是另一个控件的子控件,则它是 在将该控件添加到另一个控件之前将其从该控件中删除

这意味着您需要创建新控件,而不是在模板中添加这些控件

另一种方法是创建一个返回模板面板的方法。当您需要模板面板时,只需调用该方法,就会创建一个新面板:

public static Panel CreateTemplatePanel() {
    Panel pn = new Panel();
    // set properties, add controls...
    return pn;
}
你不是在“复制”控件。你在移动它们。当我把一罐啤酒从冰箱里拷贝到胃里时,为什么它会从冰箱里消失?在案件接近尾声之前,这不应该令人困惑。