控件已从旧的父控件中删除,但如果我使用 List<Control> 则不会,为什么?

Control is removed from old parent control but not if i use a List<Control>, why?

这可能是一个关于 C# 和 WebControl 行为的非常基本的问题。我得到了这个工作,但如果有人能澄清差异所在,那就太好了。

之前

我有一个带有给定键 (Guid) 和 Panel 的字典。

var tmpFormButtonPanel = new Panel();
 _formButtonPanelDict.TryGetValue(new Guid(_hiddenField.Value), out tmpFormButtonPanel);

此面板包含 WebControl。现在我想将此按钮分配给另一个面板。

if (tmpFormButtonPanel != null)
{
       var tmpControls = new List<Button>();
       foreach (Button tmpButton in tmpFormButtonPanel.Controls)
       {
            tmpControls.Add(tmpButton);
       }
       tmpControls.Reverse();
       foreach (var tmpButton in tmpControls)
       {
           tmpButton.AddCssClass("xy");
           _buttonPanel.Controls.Add(tmpButton);
       }
}

当我将按钮添加到 _buttonPanel 时,它会从 tmpFormButtonPanel 中删除按钮。据我所知,WebControl 只能分配给一个面板。所以这可以解释为什么它不起作用。

所以我把代码改成了这样。

var tmpFormButtonList = new List<ButtonBaseUc>();
 if (!_formButtonDict.TryGetValue(new Guid(_hiddenField.Value), out tmpFormButtonList))
{
       tmpFormButtonList = new List<ButtonBaseUc>();
       _formButtonDict.Add(new Guid(_hiddenField.Value), tmpFormButtonList);
}
foreach (var tmpButton in tmpFormButtonPanel.Controls)
{
       if (tmpButton is ButtonBaseUc)
       {
            tmpFormButtonList.Add((ButtonBaseUc)tmpButton);
       }
}

最后一部分做同样的事情,但是在 tmpFormButtonList.

if (tmpFormButtonList!= null)
{
    var tmpControls = new List<Button>();
    foreach (Button tmpButton in tmpFormButtonList)
    {
         tmpControls.Add(tmpButton);
    }
    tmpControls.Reverse();
    foreach (var tmpButton in tmpControls)
    {
          tmpButton.AddCssClass("xy");
          _buttonPanel.Controls.Add(tmpButton);
     }
  }

这是有效的。但为什么?我只是在将按钮添加到新面板之前将其分配给另一个列表。引用还是一样的。我错过了什么?

一个控件只能属于一个父控件。由于您已将其分配给字典值中的 Panel,因此如果将其移至 _buttonPanel,它将在那里被删除。

这不是 documented but you can see it in the source:

// ...
if (control._parent != null) {
   control._parent.Controls.Remove(control);
}

您已通过不使用 Panel 作为 "storage" 而是使用 List<ButtonBaseUc> 来解决此问题。此列表不是控件(因此该控件没有父控件),因此如果您将它分配给另一个(父控件)控件,则不得删除它。