6

包括一个展示我的问题的小项目。我TPageControl与主表格对齐。在两个标签页中的每一个上,我都有面板客户端对齐。在每个面板上,我都有 2 个子面板和一个分离器。左侧面板和分离器左对齐,右侧面板客户端对齐。

基本上问题是两个选项卡之间的交互。展示:

  • 运行程序
  • 水平拉伸主窗体。面板 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 回答 4

4

MinWidth要获得预期的行为,请从面板中删除约束 ( )。无论如何,这些设置目前都无效MinSize,因为您的拆分器的 a为“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;
于 2011-01-29T13:00:45.987 回答
2

不一定是真正的答案,但有几点意见:

  • MinSize 或 alLeft 对齐的 Splitter 属于 Splitter 左右两侧的控件。您的 Panel 6 确实调整为(略大于)其自己的 minWidth (10) 而不是拆分器的 MinSize (30)。您可以通过在每个面板 2、3、5 和 6 上添加两个左对齐面板并为它们提供 10 和 20 的宽度和不同的颜色来更轻松地演示这一点。

  • 在减小主窗体的宽度后再次选择选项卡,确实会增大主窗体(yikes)并且显示现在 Panel3 现在也已减小到其最小宽度而不是拆分器的 minSize。

主窗体调整大小的解决方案?不知道,但确保面板的最小宽度与拆分器的最小尺寸同步应该可以消除收缩。正如 Sertac 所说,我怀疑您只需要选择其中一个,而不是两者都...

更新:

  • 将拆分器的 minSize 设置为 30,并将面板的 minWidth 设置为 0。取消主窗体的调整大小,但确实将右侧面板的宽度减小到 0。

  • 将拆分器的 minSize 设置为 30 并将面板的 minWidth 设置为 30,消除了最小宽度问题,但仍调整了主窗体的大小。

  • 将面板的 minWidth 设置为 30 并将拆分器的 minSize 设置为 1(最小值)允许您将拆分器一直向右移动,并在释放拆分器时通过面板 minWidth 调整主窗体的大小。它确实使 Panel6 不会减少到小于 30,但是当您重新选择选项卡 1 时,主窗体会再次调整大小。

看起来您最好的选择是依靠分离器的 minSize 并“手动”通过限制分离器在最右边时的移动来防止右侧面板减少到很远。您可以在拆分器的 OnCanResize 事件中执行此操作。

顺便说一句,使用 D2009

于 2011-01-29T13:03:04.533 回答
1
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;
}
于 2012-05-26T06:01:05.477 回答
0

如果在表单较宽时将拆分器移到右侧很远,然后减小表单的宽度,使其比左侧面板更窄(因此拆分器发现自己在表单“外部”),您的表单的行为应该是什么在这种情况下?有人问过您对理想行为的标准,到目前为止,我在您的回答中只能看到您对理想行为的理解。

现在,我曾多次担心调整具有面板和拆分器的表单的大小可能产生的副作用。我没有对此进行太多调查,因此特别是我以前从未知道像您的情况那样的自动调整大小效果。无论如何,为了防止大多数(如果不是任何)可能的行为伪影,我考虑将TScrollBox其用作面板和拆分器的父控件,而不是TPanel.

我相信,这会将表单的大小调整更改为滚动框客户区域的大小调整,如果我像您一样使用标签表,那么这对我来说在我使用拆分器的少数小项目中都可以正常工作。但是我不知道你的情况。而且我知道这更多的是一种解决方法,而不是解决您的问题的方法。

于 2011-01-30T19:55:36.030 回答