как мне избежать этого нежелательного поведения с помощью Delphi TSplitter и панелей? - PullRequest
6 голосов
/ 29 января 2011

Включен небольшой проект, демонстрирующий мою проблему.У меня TPageControl выровнен по основной форме.На каждой из двух вкладок я выровнял панели клиента.На каждой из этих панелей у меня есть 2 подпанели и сплиттер.Панель LH и сплиттер выровнены по левому краю, панель RH выровнена по клиенту.

В основном проблема заключается в взаимодействии между двумя вкладками.Для демонстрации:

  • запустите программу
  • растяните основную форму горизонтально.Панель 3 вырастет
  • и переместит сплиттер вправо до упора.Панель 2 будет расти, панель 3 будет уменьшена до минимального значения ширины в 10 пикселей.
  • выберите вкладку 2. Панель 5 соответствует заданным параметрам, панель 6 выросла при растяжении основной формы
  • уменьшите ширину основной формы до ее первоначальной ширины.Панель 6 слишком сильно сжимается (нежелательно)
  • нажмите на таблицу 1. Ширина главной формы снова увеличивается (нежелательно)

ОК, поведение, вероятно, объяснимо с точки зрения правилвыровненные панели, но кто-нибудь может предложить улучшения в работе?

unit Unit17;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ComCtrls;

type
  TForm17 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Panel1: TPanel;
    Panel2: TPanel;
    Splitter1: TSplitter;
    Panel3: TPanel;
    Panel4: TPanel;
    Splitter2: TSplitter;
    Panel5: TPanel;
    Panel6: TPanel;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form17: TForm17;

implementation

{$R *.dfm}

end.


object Form17: TForm17
  Left = 0
  Top = 0
  Caption = 'Form17'
  ClientHeight = 254
  ClientWidth = 314
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object PageControl1: TPageControl
    Left = 0
    Top = 0
    Width = 314
    Height = 254
    ActivePage = TabSheet1
    Align = alClient
    Constraints.MinWidth = 30
    TabOrder = 0
    ExplicitWidth = 480
    object TabSheet1: TTabSheet
      Caption = 'TabSheet1'
      ExplicitWidth = 281
      ExplicitHeight = 165
      object Panel1: TPanel
        Left = 0
        Top = 0
        Width = 306
        Height = 226
        Align = alClient
        Caption = 'Panel1'
        TabOrder = 0
        ExplicitWidth = 109
        ExplicitHeight = 165
        object Splitter1: TSplitter
          Left = 151
          Top = 1
          Width = 12
          Height = 224
          ExplicitLeft = 145
        end
        object Panel2: TPanel
          Left = 1
          Top = 1
          Width = 150
          Height = 224
          Align = alLeft
          Caption = 'Panel2'
          Constraints.MinWidth = 10
          TabOrder = 0
        end
        object Panel3: TPanel
          Left = 163
          Top = 1
          Width = 142
          Height = 224
          Align = alClient
          Caption = 'Panel3'
          Constraints.MinWidth = 10
          TabOrder = 1
          ExplicitLeft = 141
          ExplicitWidth = 330
        end
      end
    end
    object TabSheet2: TTabSheet
      Caption = 'TabSheet2'
      ImageIndex = 1
      ExplicitWidth = 281
      ExplicitHeight = 165
      object Panel4: TPanel
        Left = 0
        Top = 0
        Width = 306
        Height = 226
        Align = alClient
        Caption = 'Panel4'
        TabOrder = 0
        ExplicitWidth = 109
        ExplicitHeight = 165
        object Splitter2: TSplitter
          Left = 149
          Top = 1
          Width = 11
          Height = 224
          ExplicitLeft = 141
        end
        object Panel5: TPanel
          Left = 1
          Top = 1
          Width = 148
          Height = 224
          Align = alLeft
          Caption = 'Panel5'
          Constraints.MinWidth = 10
          TabOrder = 0
        end
        object Panel6: TPanel
          Left = 160
          Top = 1
          Width = 145
          Height = 224
          Align = alClient
          Caption = 'Panel6'
          Constraints.MinWidth = 10
          TabOrder = 1
          ExplicitLeft = 141
          ExplicitWidth = 139
          ExplicitHeight = 163
        end
      end
    end
  end
end 

Ответы [ 4 ]

4 голосов
/ 29 января 2011

Чтобы получить ожидаемое поведение, удалите ограничения (MinWidth) с ваших панелей. Эти настройки в настоящее время неэффективны в любом случае, так как ваши сплиттеры имеют MinSize из 30 (по умолчанию, не сохраняется).

edit (ответ на комментарий): Вы не можете ожидать, что ограничение 'MinWidth' элемента управления, расположенного справа от разделителя, отрегулирует размер элемента управления слева. Это логично, ограничение является свойством для элемента управления, который вы устанавливаете. Все, чего вы добьетесь - это то, что форма будет отрицать сокращение, если ваш элемент управления уже имеет минимальную ширину, следовательно, нежелательное поведение , которое вы наблюдаете, когда форма увеличивается при переключении вкладок. То, что вы хотите, вы должны делать с кодом - как сказал Марьян в своем ответе. Для этого должно быть несколько способов, например, поместить приведенное ниже в событие OnCanResize Panel3:

procedure TForm1.Panel3CanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
  if NewWidth < Splitter1.MinSize then
    Panel2.Width := Panel2.Width - Splitter1.MinSize + NewWidth;
end;
2 голосов
/ 29 января 2011

Не обязательно реальный ответ, но пара замечаний:

  • MinSize или AlLeft выровненный Splitter относится к элементу управления Splitter слева и справа.Размер вашей Panel 6 действительно (немного больше) собственного minWidth (10) вместо MinSize (30) разделителя.Вы можете легко продемонстрировать это, добавив две выровненные по левому краю панели на каждую из ваших панелей 2, 3, 5 и 6 и назначив им ширину 10 и 20 и другой цвет.

  • Снова выбирая табулированную таблицу один после уменьшения ширины основной формы, она расширяет основную форму (yikes) И показывает, что теперь Panel3 теперь также уменьшена до ее минимальной ширины вместо minSize разделителя.

решение основной формы изменения размера?Не знаю, но убедившись в том, что минимальная ширина ваших панелей синхронизирована с минимальным размером сплиттеров, следует устранить сокращение.И, как говорит Сертак, я подозреваю, что вам просто нужно выбрать один или другой, но не оба ...

Обновление:

  • Установка minSize разделителей30 и установка minWidth панелей на 0. Снимает изменение размера основной формы, но уменьшает правые панели до 0 ширины.

  • Установка minSize разделителей на 30 и установкаminWidth панелей до 30, устраняет проблемы минимальной ширины, но все еще изменяет размер основной формы.

  • Установка minWidth панелей равной 30 и установка minSize разделителей равной 1 (минимальное) позволяет перемещать сплиттер полностью вправо и изменяет размеры основной формы с помощью панелей minWidth при отпускании сплиттера.Это удерживает Panel6 от сокращения до менее 30, но опять же основная форма изменяется при повторном выборе вкладки 1.

Казалось бы, лучше всего полагаться на minSize и разделители.«вручную» не позволяют правым панелям уменьшаться до предела, ограничивая движение сплиттеров, когда они доходят до правого краяВы можете сделать это в событии OnCanResize разделителей.

btw, используя D2009

1 голос
/ 26 мая 2012
void __fastcall TFMain::SplitterCanResize(TObject *Sender, int &NewSize, bool &Accept)
{
  TSplitter *S = (TSplitter *)Sender;
  for (int i = 0; Accept && i < S->Parent->ControlCount; i++) if (S->Parent->Controls[i]->Constraints->MaxHeight && S->Parent->Controls[i]->Align == S->Align && NewSize >= S->Parent->Controls[i]->Constraints->MaxHeight * 2) Accept = false;
}
0 голосов
/ 30 января 2011

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

Теперь меня несколько раз беспокоилоВозможные побочные эффекты изменения размера формы с панелями и разделителями.Я не очень подробно разбирался в этом, и поэтому, в частности, я никогда раньше не знал об эффекте автоматического изменения размера, как в ваших ситуациях.В любом случае, для предотвращения большинства (если не каких-либо) возможных поведенческих артефактов, которые я рассмотрел, я использовал TScrollBox в качестве родительского элемента управления для панелей и разделителей вместо TPanel.

Я считаю, что это изменит изменение размеровформы для изменения размера клиентской области окна прокрутки, что будет хорошо работать для меня, хотя в нескольких моих небольших проектах, где я использовал сплиттеры, если бы я использовал табуляцию, как вы.Однако я не могу знать о вашем случае.И я понимаю, что это скорее обходной путь, чем решение вашей проблемы.

...