SplitContainer collapsed, child form dock issue
-
Thursday, June 28, 2012 2:49 PM
Hi there,
I'm new here, and I'm italian (sorry 4 my bad english).
I got an issue with C# WinForms.
My main form has a SplitContainer that hosts a nested panel into its panel2 (dock is set to Fill).
I know that this can sound bad, but changing that is not an option [...].
During runtime, I create an instance of a child form (plz, take a look at the following code):
var frm = (Form)Activator.CreateInstance(FormType);
frm.TopLevel = false;
frm.Parent = pnlAppSpace; //this is the panel into SplitContainer.Panel2
frm.Dock = DockStyle.Fill;
frm.Show();All works fine until I collapse the SplitContainr.Panel1 (this is a sort of toggle button click event handler):
splitContainerMain.IsSplitterFixed = false;
splitContainerMain.Panel1Collapsed = !splitContainerMain.Panel1Collapsed;
splitContainerMain.IsSplitterFixed = true;While the pnlAppSpace looks to be ok (it's shrinked to fit the new bigger area, using the space on the left provided by the collapsed panel1), I get the child form in the pnlAppSpace not properly resized to fill its parent bigger area: in other words, you can see on its right its parent background, as the form had been dragged to the left, leaving a hole on the right! I was expecting the child form to resize in order to fit the pnlAppSpace, having the panel1 collapsed and all the nested controls dock property set to Fill!
What I'm forgetting about?
I've tried to play with it, but I ain't found a solution yet.Dock.Fill->Normal->Fill fixes something but creates other bugs ...PerformLayout() no way ...this is not a SuspendLayout issue, as I tested it disabling the layout tricks. I'm screwing up with this thing, plz help me :)
All my controls use DoubleBuffer, and my splitContainerMain is a derived class (just to render the content as a whole thing, to get rid of the hateful flickering effect):
public class SmartSplitContainer : SplitContainer
{
public SmartSplitContainer()
{
DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
MethodInfo mi = typeof(Control).GetMethod("SetStyle", BindingFlags.NonPublic | BindingFlags.Instance);
object[] args = new object[] { ControlStyles.OptimizedDoubleBuffer, true };
mi.Invoke(this.Panel1, args);
mi.Invoke(this.Panel2, args);
}
}Hope I wrote the relevant information, in a clearly understandable way.
Tnx in advance!
Marco
EDIT:
If I set the child form's WindowState to Normal, all is right!!! But I previously set it to Maximized in design time to void the stratching effect on form shown... I would like to start up the child form maximized (no resize flickering), but get rid of the missing resize when panel1 is collapsed. Why this happens?!
Tnx! :)
- Edited by RomaNord Thursday, June 28, 2012 3:43 PM News!
All Replies
-
Monday, July 02, 2012 5:23 AMModerator
Hi RomaNord,
As far as I know, the size of form cannot be changed when its WindowState is Maximized. And when the WindowState is set to Maximized, it will automaticlly resize the form. If we want to adjust the size to its parent, maybe we should set the WindowState.
form.WindowState = FormWindowState.Normal; form.WindowState = FormWindowState.Maximized;
However, it may cause the resize flickering which you do not want.
You have said that when you change the WindowState to Normal, "all is right". So there is no flicking now?
If there are any new findings, please feel free to let me know.
Best regards,
Chester Hong
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
Monday, July 02, 2012 8:20 PM
Thank you for the quick answer, first of all!
You are right, Maximized forms don't use form size, so they cannot be resized (meaning changing their size specifying new values) and I really don't want to manage that thing. I've just trusted the built-in autoresizing stuff as I've set form.Dock=Fill and form.WindowState=Maximized (both in design time).
But... although I get the automatic autoresize working well when I have a Normal WindowState child form, it incredibly fails when I use maximized child forms, why?! This is what I really don't understand, why an automatic built-in thing seems to be buggy, as it has "asymmetric" behaviour.
Switching the WindowState back and forth through Maximized and Normal or viceversa is not the answer to the problem, because it solves this problem, but simply moves the issue to another moment of the runtime:
the whole app loads maximized, and the child form is created maximized and fill-docked; I click the "normalize button" in the main form control box, all right; then I make the splitcontainer collapse panel1 and I correctly get the panel2 fill job done. But if I toggle the splitter back to the expanded mode, and I click the "Maximize button" in the main form control box, I get the child form not entirely autoresized to fill all the available parent area! This bug never happens if I start with my child form's window state as normal. Here is the code I call from the main form when I set the child form to Maximized in design time:
private void btnSplitter_Click(object sender, EventArgs e)
{
try
{
pnlAppSpace.SuspendLayout();//AdaptAppSize(false);
splitContainerMain.IsSplitterFixed = false;
splitContainerMain.Panel1Collapsed = !splitContainerMain.Panel1Collapsed;
splitContainerMain.IsSplitterFixed = true;
pnlAppSpace.ResumeLayout();//AdaptAppSize(true);
AdaptAppSize();
}
catch (Exception ex)
{
Utilities.ErrorManager.ShowMessage(ex, frmMain.ActiveForm);
}
finally
{
pnlAppSpace.ResumeLayout();
}
}private void AdaptAppSize()
{
foreach (Control c in pnlAppSpace.Controls)
{
Form f = c as Form;if (f != null)
{
f.WindowState = FormWindowState.Normal;
f.WindowState = FormWindowState.Maximized;
}
}
}The best way for me by now is to set form.WindowState=Normal in design time, to enlarge the form in the designer (and obviously comment the AdaptAppSize call). What I'm looking for is just to set the form Maximized and get the same behaviour I get with Normal.
Thanks again for your time!
Marco
-
Wednesday, July 04, 2012 10:19 AMModerator
Thanks for your researching.
It is true that this is not an answer to set the WindowState back and forth, but I really cannot find a good solution now.
I'm introducing more senior engineers to this thread to see whether there are better solutions to solve this issue.
Best regards,
Chester Hong
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
Wednesday, July 04, 2012 12:48 PM
Thanks again for your help!
These are the screenshots of what happens if I use a Maximized child form. If I toggle Maximized-Normal-Maximized I get this same issue when I normalize the main form, as I described before. I ain't found a bugless way using WindowsState=Maximized at design-time: we just move the same bug to a different scenario toggling the WindowState back and forth in runtime.
It looks like that the child form's dock-fill built-in autoresize would forget to do its job when the form had to grow and has the WindowState set to Maximized. The parent-child structure is the following: MainForm[SplitContainer.panel2[Panel[ChildForm]]].
Thanks.
Marco
- Edited by RomaNord Wednesday, July 04, 2012 2:01 PM
-
Monday, August 13, 2012 6:32 AM
Hi,
You could visit the below link to see the various paid support options that are available to better meet your needs if you requires a more in-depth level of support.
http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone
Regards -
Thursday, September 13, 2012 4:14 PM
Thanks, but finally I've made a rude workaround, and it does work perfectly.
I answer now cause I was on holidays [...my 1st time in the States, wow!]
I had to combine 2 actions:
1) refresh the dock state and size of my appPanel while switching the splitter.
2) Add a FixWidth method in the base class for all my App forms, using the WorkingArea width (and all the stuff in order to be robust to all recent Windows versions and desktop settings).
...it's a very rude solution, I know, but since I'm pretty sure that the cleanest way would require a deep override work affecting the panel class, I'll care about that in a second time. If I find a cool fix I'll post it here, of course.
Best regards


