Reputation: 56660
I'm writing a WinForms application and one of the tabs in my TabControl has a SplitContainer. I'm saving the SplitterDistance in the user's application settings, but the restore is inconsistent. If the tab page with the splitter is visible, then the restore works and the splitter distance is as I left it. If some other tab is selected, then the splitter distance is wrong.
Upvotes: 10
Views: 8281
Reputation: 21
Save the splitter distance as a percentage of the split container height. Then restore the splitter distance percentage using the current split container height.
/// <summary>
/// Gets or sets the relative size of the top and bottom split window panes.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[UserScopedSetting]
[DefaultSettingValue(".5")]
public double SplitterDistancePercent
{
get { return (double)toplevelSplitContainer.SplitterDistance / toplevelSplitContainer.Size.Height; }
set { toplevelSplitContainer.SplitterDistance = (int)((double)toplevelSplitContainer.Size.Height * value); }
}
Upvotes: 2
Reputation: 570
Set the containing TabPage.Width = TabControl.Width - 8 before setting the SplitContainer.SplitDistance
Upvotes: 0
Reputation: 410
As it was mentioned, control with SplitContainer doesn't get resized to match the tab control until it gets selected. If you handle restoring by setting SplitterDistance in percentage (storedDistance * fullDistance / 100) in case of FixedPanel.None, you will see the splitter moving in some time because of precision of calculations.
I found another solution for this problem. I subscribes to one of the events, for example Paint event. This event comes after control’s resizing, so the SplitContainer will have correct value. After first restoring you should unsubscribe from this event in order to restore only once:
private void MainForm_Load(object sender, EventArgs e)
{
splitContainerControl.Paint += new PaintEventHandler(splitContainerControl_Paint);
}
void splitContainerControl_Paint(object sender, PaintEventArgs e)
{
splitContainerControl.Paint -= splitContainerControl_Paint;
// Handle restoration here
}
Upvotes: 5
Reputation: 1
Answer is time synchrinizations. You must set SplitterDistance when window is done with size changing. You must then flag for final resize and then set SplitterDistance. In this case is all right
Upvotes: 0
Reputation: 1163
I had the same problem. In my particular case, I was using forms, that I transformed into tabpages and added to the tab control. The solution I found, was to set the splitter distances in the Form_Shown event, not in the load event.
Upvotes: 3
Reputation: 316
Restoring splitter distances has given me a lot of grief too. I have found that restoring them from my user settings in the form (or user control) Load event gave much better results than using the constructor. Trying to do it in the constructor gave me all sorts of weird behaviour.
Upvotes: 0
Reputation: 7877
For handling all cases of FixedPanel and orientation, something like the following should work:
var fullDistance =
new Func<SplitContainer, int>(
c => c.Orientation ==
Orientation.Horizontal ? c.Size.Height : c.Size.Width);
// Store as percentage if FixedPanel.None
int distanceToStore =
spl.FixedPanel == FixedPanel.Panel1 ? spl.SplitterDistance :
spl.FixedPanel == FixedPanel.Panel2 ? fullDistance(spl) - spl.SplitterDistance :
(int)(((double)spl.SplitterDistance) / ((double)fullDistance(spl))) * 100;
Then do the same when restoring
// calculate splitter distance with regard to current control size
int distanceToRestore =
spl.FixedPanel == FixedPanel.Panel1 ? storedDistance:
spl.FixedPanel == FixedPanel.Panel2 ? fullDistance(spl) - storedDistance :
storedDistance * fullDistance(spl) / 100;
Upvotes: 4
Reputation:
There`s a more easy solution. If Panel1 is set as the fixed panel in SplitContainer.FixedPanel property it all behaves as expected.
Upvotes: 18
Reputation: 56660
I found the problem. Each tab page doesn't get resized to match the tab control until it gets selected. For example, if the tab control is 100 pixels wide in the designer, and you've just set it to 500 pixels during load, then setting the splitter distance to 50 on a hidden tab page will get resized to a splitter distance of 250 when you select that tab page.
I worked around it by recording the SplitterDistance and Width properties of the SplitContainer in my application settings. Then on restore I set the SplitterDistance to recordedSplitterDistance * Width / recordedWidth.
Upvotes: 7