如何使用Delphi的TSplitter和面板避免这种不必要的行为?

ros*_*mcm 6 delphi delphi-2006 tpanel ttabsheet

包括一个展示我的问题的小项目.我有一个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 
Run Code Online (Sandbox Code Playgroud)

Ser*_*yuz 4

MinWidth为了获得预期的行为,请从面板中删除约束 ( )。无论如何,这些设置目前无效,因为您的分离器的值为MinSize“30”(默认值,未存储)。

编辑(对评论的回应):您不能指望位于拆分器右侧的控件的“MinWidth”约束来调整左侧控件的大小。这是合乎逻辑的,约束是您设置的控件的属性。您将实现的只是,如果您的控件已经处于“MinWidth”,则表单将拒绝缩小,因此您会在切换选项卡时观察到表单变大的不良行为。正如 Marjan 在他的回答中所说,你想要什么,就必须与代码有关。应该有不止一种方法可以实现此目的,例如,将以下内容添加到 Panel3 的“OnCanResize”事件中:

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;
Run Code Online (Sandbox Code Playgroud)