I have a process which uses recursion to generate controls from XML. The system is complicated. I’ve broken down as small as I can. The last Plugin is visible, the rest are not. I suspect GenerateControls() is broken. Why don’t all the plugins display?
Form:
public partial class PdLoadingForm : Form
{
public PdLoadingForm()
{
InitializeComponent();
PhysDocDocument document = MockDocument();//Generate some mock data
GenerateControls(document.Nodes);//Generate controls using recursion.
}
private PhysDocDocument MockDocument()
{
PhysDocDocument document = new PhysDocDocument();
PhysDocNode outerNode = new PhysDocNode();
outerNode.Display = "outer Node";
//Generate 3 plugins. Each plugin generates a textbox. I only see 1 Textbox.
//I expect to see 3 textboxes.
for(int i = 0; i < 3; i++)
{
PhysDocNode innerNode = new PhysDocNode() { Display = "test" + i };
PhysDocNode innerNodeContent = new PhysDocNode() { Display = "IO" };
innerNodeContent.Plugins.Add(new Plugin());
innerNode.Nodes.Add(innerNodeContent);
outerNode.Nodes.Add(innerNode);
}
document.Nodes.Add(outerNode);
return document;
}
private void GenerateControls(List<PhysDocNode> children, CustomControl parent = null)
{
foreach (PhysDocNode node in children)
{
CustomControl parentControl = new CustomControl(node);
if (node.Nodes != null && node.Nodes.Count > 0)
GenerateControls(children: node.Nodes, parent: parentControl);
foreach (Plugin plugin in node.Plugins)
{
Control childControl = plugin.CreateUIControl();//Ask the plugin for a control
AddControl(childControl: childControl, parent: parentControl);
}
AddControl(childControl: parentControl, parent: parent);
}
}
private void AddControl(Control childControl, Control parent)
{
childControl.Dock = DockStyle.Top;
if(parent == null)//add to form
Controls.Add(childControl);
else//add to parent
parent.Controls.Add(childControl);
}
}
Plugin:
public class Plugin
{
[XmlAttribute]
public string type { get; set; }
public Control CreateUIControl()
{
TextBox testBox = new TextBox();
testBox.Text = "plugin";
return testBox;
}
}
CustomControl:
public class CustomControl: UserControl
{
public CustomControl(PhysDocNode nodeInfo)
{
InitializeComponent();
Label label = new Label();
label.Text = "Rtb..." + nodeInfo.Display;
label.Dock = DockStyle.Top;
contentPanel.Controls.Add(label);//just drop a panel on the user control in design view
}
Looking at the documentation, it seems that the Dock property manage the positionning of the label relatively to its parent.
You may try to specify the label position by, for example, setting its Top property‘s value to a multiple of its index in your control list.