Search code examples
c#controlspanels

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


I created a template panel to go by when my form loads that holds a record. When adding a new record I have a method that duplicates that template panel and then adds it to my list of panels for each record. Somehow controls are getting deleted from my template panel when I am duplicating it and I have no idea how this is happening. The portion of code doing this is listed below

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

I put the messagebox.show() in at 3 points to narrow down where it is happening. The first one shows the correct number of controls, the second and third shows a 1/2 the total amount of controls. why is this?


Solution

  • This is because each control can be added to only one parent control. All controls in your template panel are already a child of the template panel. When you try to add these controls to a new panel, the controls will get removed from the template panel.

    As per the 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.

    Which means that you need to create new controls instead of adding those in the template.

    An alternative approach is to create a method that returns the template panel. When you need the template panel, just call the method and a new panel will be created:

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