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.
我正在编写一个WinForms应用程序,我的TabControl中的一个选项卡有一个SplitContainer。我将SplitterDistance保存在用户的应用程序设置中,但恢复不一致。如果带有拆分器的标签页可见,则恢复工作,拆分器距离就像我离开时一样。如果选择了其他选项卡,则分割器距离错误。
9 个解决方案
#1
16
There`s a more easy solution. If Panel1 is set as the fixed panel in SplitContainer.FixedPanel property it all behaves as expected.
有一个更简单的解决方案。如果在SplitContainer.FixedPanel属性中将Panel1设置为固定面板,则它们都按预期运行。
#2
7
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.
我发现了问题。在选中之前,每个选项卡页面都不会调整大小以匹配选项卡控件。例如,如果设计器中的选项卡控件宽度为100像素,并且您在加载期间只将其设置为500像素,则在隐藏选项卡页面上将分割器距离设置为50将调整为分配器距离250时的大小您选择该标签页。
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.
我通过在我的应用程序设置中记录SplitContainer的SplitterDistance和Width属性来解决它。然后在恢复时我将SplitterDistance设置为recordedSplitterDistance * Width / recordedWidth。
#3
5
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.
如前所述,使用SplitContainer进行控制不会调整大小以匹配选项卡控件,直到它被选中。如果在FixedPanel.None的情况下通过设置SplitterDistance的百分比(storedDistance * fullDistance / 100)来处理恢复,则由于计算的精确性,您将看到分离器在一段时间内移动。
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:
我找到了解决这个问题的另一种方案我订阅了其中一个事件,例如Paint事件。此事件在控件调整大小后发生,因此SplitContainer将具有正确的值。首次恢复后,您应取消订阅此活动,以便仅恢复一次:
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
}
#4
4
For handling all cases of FixedPanel and orientation, something like the following should work:
要处理所有FixedPanel和方向的情况,以下内容应该起作用:
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;
#5
3
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.
我有同样的问题。在我的特定情况下,我正在使用表单,我转换为tabpages并添加到选项卡控件。我发现的解决方案是在Form_Shown事件中设置分割器距离,而不是在load事件中。
#6
2
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); }
}
#7
0
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.
恢复分离器距离也给我带来了很多悲伤。我发现从表单(或用户控件)Load事件中的用户设置恢复它们比使用构造函数提供了更好的结果。试图在构造函数中执行它给了我各种奇怪的行为。
#8
0
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
答案是时间同步。当窗口完成大小更改时,您必须设置SplitterDistance。然后必须标记为最终调整大小,然后设置SplitterDistance。在这种情况下是可以的
#9
0
Set the containing TabPage.Width = TabControl.Width - 8 before setting the SplitContainer.SplitDistance
在设置SplitContainer.SplitDistance之前设置包含TabPage.Width = TabControl.Width - 8
#1
16
There`s a more easy solution. If Panel1 is set as the fixed panel in SplitContainer.FixedPanel property it all behaves as expected.
有一个更简单的解决方案。如果在SplitContainer.FixedPanel属性中将Panel1设置为固定面板,则它们都按预期运行。
#2
7
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.
我发现了问题。在选中之前,每个选项卡页面都不会调整大小以匹配选项卡控件。例如,如果设计器中的选项卡控件宽度为100像素,并且您在加载期间只将其设置为500像素,则在隐藏选项卡页面上将分割器距离设置为50将调整为分配器距离250时的大小您选择该标签页。
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.
我通过在我的应用程序设置中记录SplitContainer的SplitterDistance和Width属性来解决它。然后在恢复时我将SplitterDistance设置为recordedSplitterDistance * Width / recordedWidth。
#3
5
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.
如前所述,使用SplitContainer进行控制不会调整大小以匹配选项卡控件,直到它被选中。如果在FixedPanel.None的情况下通过设置SplitterDistance的百分比(storedDistance * fullDistance / 100)来处理恢复,则由于计算的精确性,您将看到分离器在一段时间内移动。
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:
我找到了解决这个问题的另一种方案我订阅了其中一个事件,例如Paint事件。此事件在控件调整大小后发生,因此SplitContainer将具有正确的值。首次恢复后,您应取消订阅此活动,以便仅恢复一次:
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
}
#4
4
For handling all cases of FixedPanel and orientation, something like the following should work:
要处理所有FixedPanel和方向的情况,以下内容应该起作用:
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;
#5
3
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.
我有同样的问题。在我的特定情况下,我正在使用表单,我转换为tabpages并添加到选项卡控件。我发现的解决方案是在Form_Shown事件中设置分割器距离,而不是在load事件中。
#6
2
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); }
}
#7
0
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.
恢复分离器距离也给我带来了很多悲伤。我发现从表单(或用户控件)Load事件中的用户设置恢复它们比使用构造函数提供了更好的结果。试图在构造函数中执行它给了我各种奇怪的行为。
#8
0
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
答案是时间同步。当窗口完成大小更改时,您必须设置SplitterDistance。然后必须标记为最终调整大小,然后设置SplitterDistance。在这种情况下是可以的
#9
0
Set the containing TabPage.Width = TabControl.Width - 8 before setting the SplitContainer.SplitDistance
在设置SplitContainer.SplitDistance之前设置包含TabPage.Width = TabControl.Width - 8