Given the following situation, the order of docking of controls is working incorrectly, whereas docking without using an UltraPanel, or using a Microsoft panel, is working as expected:
Base form has a dock fill UltraPanel, with inside a button docked top.
Both the panel and button are defined protected.
In a derived form we add another button, also docked top.
The newly added button should be shown underneath the docked button from the base class.
At first this looks ok at design time, but at runtime the order of the buttons is reversed. Also closing the design and reopening again already shows that the order of the panels isn't kept: the last added control to the panel is at the top.
In a Microsoft panel, or without using panels, this is solved by designer generated code that like this:
panel1.Controls.SetChildIndex(this.TopButton, 0);panel1.Controls.SetChildIndex(this.NextTopButton, 0);
The code above is not getting generated when using an UltraPanel, but is when using a Microsoft panel, or no panel at all.
It this a bug in the UltraPanel and/or is there a workaround/fix besides manually adding the lines above to the constructor? I want to see the correct result at design time as well, and not only in code as that would quickly become confusing...
I tried this out and I see the same behavior. But I don't think there's anything we can do about this. The DotNet Form Designer is apparently doing something to handle this by adding those extra lines of code. I suspect it is unable to "fix" the control position when using the UltraPanel because the controls you add to the UltraPanel are not added to the UltraPanel directly. The UltraPanel has a second panel control inside it (the ClientArea) and there's where the controls are contained. So whatever logic the DotNet framework is using to handle the control order apparently doesn't take this into account.
I also tried doing the same thing using the inbox SplitContainer control and it, too, displays the same behavior as UltraPanel - which makes sense since it's essentially doing the same thing, nesting panel controls.
I have attached my sample project here so you can see that both the SplitContainer and the UltraPanel display the same behavior.
You can, of course, work around this pretty easily by simply adding in the same code that calls SetChildIndex yourself. You can do this in the form's constructor after the call to InitializeComponent. I did this in my sample, but commented it out.
Thanks for looking into this.
I was wondering if the code generator of the .NET Visual Designer can somehow be extended to add these extra lines of code.
Sure I can add these manually as a workaround to the constructor, but that would cause the visual representation in the designer to be different than the runtime view...
The .NET framework currently knows how to generate the InitializeComponent code, so perhaps this can be extended for UltraPanel?
I've quickly searched and came across this post which hints at customizing the generator code: https://stackoverflow.com/questions/1566069/how-to-provide-custom-code-for-initializecomponent and especially https://msdn.microsoft.com/en-us/library/ms973818.aspx
Perhaps this can be investigated?
Especially this part seems relevant: https://msdn.microsoft.com/en-us/library/ms973818.aspx#custcodegen_topic8
As component developers, we are generally very familiar with how the designer works. And we are certainly very familiar with ISupportInitialize. Many of our controls use this.
But I don't see any way in which that would help us here. That interface essentially gives a control a synch point for when it's Initialization code ends. It doesn't allow you to modify the designer-generated code.
In order to directly affect the designer-generated code, you need a CodeDomSerializer. And in this case, that would mean duplicating whatever logic Microsoft already has in place for the panel control. The fact that they already don't do this for nested controls (as demonstrated by the SplitContainer) suggests that they either intentionally excluded such controls or else it's just an oversight. Either way, it's really something Microsoft would need to fix.
I will use a Microsoft panel as base panel (docked fill) in which I will dock several UltraPanels. The base panel will not contain any other controls except the UltraPanels, so this seems like a reasonable workaround.
Thanks you for your time