greenhoorn greenhoorn - 11 days ago 6
C# Question

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

It's probably a very basic question about the behaviour of C# and

WebControl
. I got this working, but it would be nice if someone could clarify where the difference lays.

Before

I have a dictionary with a given key (Guid) and a
Panel
.

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


This panel contains a
WebControl
. Now I'd like to assign this button to another panel.

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


The moment I add the button to the
_buttonPanel
, it deletes the button out of
tmpFormButtonPanel
. From what I've heard or read, a WebControl can only be assigned to one panel. So this would explain why it doesn't work.

So I changed the code to this.

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


The last part does the same thing, but on the
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);
}
}


This is working. But why? I am only assigning the button to another list before adding it to the new panel. The references are still the same. What am I missing?

Answer

A control can only belong to one parent control. Since you have assigned it to the Panel in the dictionary-value, it will be removed there if you move it to the _buttonPanel.

This isn't documented but you can see it in the source:

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

You have fixed this by not using a Panel as "storage" but a List<ButtonBaseUc>. This list is not a control(so the control has no parent), hence it must not be removed if you assign it to another (parent-)control.