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?
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.