Восстановление SplitterDistance внутри TabControl несовместимо - PullRequest
10 голосов
/ 24 сентября 2008

Я пишу приложение WinForms, и одна из вкладок в моем TabControl имеет SplitContainer. Я сохраняю SplitterDistance в настройках приложения пользователя, но восстановление противоречиво. Если вкладка с разделителем видна, то восстановление работает и расстояние разделителя такое, как я его оставил. Если выбрана какая-либо другая вкладка, то расстояние для разделителя неверно.

Ответы [ 9 ]

16 голосов
/ 06 января 2009

Есть более простое решение. Если Panel1 установлена ​​как фиксированная панель в свойстве SplitContainer.FixedPanel, все ведет себя как ожидалось.

7 голосов
/ 24 сентября 2008

Я нашел проблему. Размер каждой вкладки не изменяется, чтобы соответствовать элементу управления вкладками, пока он не будет выбран. Например, если в конструкторе элемент управления вкладкой имеет ширину 100 пикселей, и вы только что установили его на 500 пикселей во время загрузки, то при установке расстояния разделителя на 50 на скрытой вкладке будет изменено расстояние до 250, Вы выбираете эту вкладку.

Я обошел это, записав свойства SplitterDistance и Width SplitContainer в настройках своего приложения. Затем, при восстановлении, я установил SplitterDistance на значение selectedSplitterDistance * Width / recordingWidth.

5 голосов
/ 15 апреля 2013

Как уже упоминалось, элемент управления с SplitContainer не изменяется в соответствии с элементом управления вкладкой, пока он не будет выбран. Если вы обрабатываете восстановление, устанавливая SplitterDistance в процентах (сохраненное сопротивление * fullDistance / 100) в случае FixedPanel.None, вы увидите, что разветвитель будет двигаться через некоторое время из-за точности вычислений.

Я нашел другое решение этой проблемы. Я подписываюсь на одно из событий, например событие 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 голосов
/ 12 июня 2009

Для обработки всех случаев 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;

Затем сделать то же самое при восстановлении

        // 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;
3 голосов
/ 25 марта 2013

У меня была такая же проблема. В моем конкретном случае я использовал формы, которые я преобразовал в вкладки и добавил к элементу управления вкладками. Решение, которое я нашел, состояло в том, чтобы установить расстояния разделителя в событии Form_Shown, а не в событии load.

2 голосов
/ 07 ноября 2014

Сохранение расстояния разделителя в процентах от высоты разделенного контейнера. Затем восстановите процент расстояния разделения, используя текущую высоту разделенного контейнера.

  /// <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); }
  }
0 голосов
/ 01 августа 2014

Установите содержащую TabPage.Width = TabControl.Width - 8 перед установкой SplitContainer.SplitDistance

0 голосов
/ 10 апреля 2013

Ответ - синхронизация времени. Вы должны установить SplitterDistance, когда окно сделано с изменением размера. Затем необходимо пометить для окончательного изменения размера и затем установить SplitterDistance. В этом случае все в порядке

0 голосов
/ 07 июня 2012

Восстановление расстояний между сплиттерами также принесло мне много горя. Я обнаружил, что восстановление их из моих пользовательских настроек в форме (или пользовательском элементе управления) события Load дало намного лучшие результаты, чем использование конструктора. Попытка сделать это в конструкторе вызвала у меня всякое странное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...