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