为什么将控件从一个面板复制到下一个面板时控件会删除

Why do controls delete when copying controls from one panel to the next

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

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);

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

根据 docs:

A Control can only be assigned to one Control.ControlCollection at a time. If the Control is already a child of another control it is removed from that control before it is added to another control.

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

另一种方法是创建一个 returns 模板面板的方法。当您需要模板面板时,只需调用该方法即可创建一个新面板:

public static Panel CreateTemplatePanel() {
    Panel pn = new Panel();
    // set properties, add controls...
    return pn;
}