Как избежать этого нежелательного поведения с Tsplitter и панелями Delphi?

StackOverflow https://stackoverflow.com/questions/4835617

Вопрос

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

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

  • Запустите программу
  • Растяните основную форму горизонтально. Панель 3 будет расти
  • Переместите сплиттер так далеко вправо, как это пойдет. Панель 2 будет расти, панель 3 будет сокращаться до своего 10-пиксельного ограничения шириной мин.
  • Выберите TabSheet 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 
Это было полезно?

Решение

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

редактировать (Ответ на комментарий): Вы не можете ожидать ограничения «MinWidth» управления, которое находится на правой стороне сплиттера, чтобы отрегулировать размер управления левой стороной. Это только логично, ограничение является свойством для установленного вами элемента управления. Все, чего вы достигнете, это то, что форма будет отрицать сокращение, если ваш контроль уже находится на его «Minweidth», отсюда нежелательно Поведение, которое вы наблюдаете, что форма становится все больше при переключении вкладок. То, что вы хотите, вы имеете отношение к коду - как сказал Марджан в своем ответе. Например, должно быть более одного способа достижения этого, чтобы поместить приведенное ниже событие «OnCanResize» панели 3:

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;

Другие советы

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

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

  • Выбор табшита снова после уменьшения ширины Mainform, выращивает Mainform (yikes) и показывает, что теперь Panel3 также также была уменьшена до его ширины минима, а не до минимального размера сплиттера.

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

Обновлять:

  • Установка расщепления до 30 и установка панелей «Минсиид» на 0. Убирает изменение размера Mainform, но снижает правую панели до 0 ширины.

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

  • Установка панелей «Minweedth» на 30 и установление MinSize расщепления до 1 (минимум) позволяет перемещать разветвитель вправо и изменяет размер основной формы на панелях MinWeidth, когда вы отпускаете сплиттер. Он не позволяет панели от сокращения до менее чем 30, но опять же, Mainform изменяется, когда вы выбираете вкладку 1.

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

Кстати, используя D2009

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;
}

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top