我的锚点有个小问题。

我有一个包含2个面板的表单,Panel1左对齐,而Panel2在第一个而不对齐的位置,而是固定在顶部和底部。在第二个面板上有两个编辑,它们仅锚定在左侧,右侧和底部。这种设计会产生“最小化”滑动效果,从而在调整表单大小时,编辑内容会在顶部消失。这是有意的。

在应用程序启动时,第二个面板的初始状态应该是不可见的,因此我使用Panel2.Height := 0

但是,在调整表单大小或手动设置Panel2.Height := 104之后,这些编辑不会下拉到其锚定位置,但在面板外仍不可见。

这是示例代码,可以帮助可视化它:

// unit 1
unit Unit1;

interface

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

type
  TMoveEvent = procedure (Sender: TObject; X, Y: Integer) of object;

  TLabeledEdit = class(ExtCtrls.TLabeledEdit)
  private
    FOnMove: TMoveEvent;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
  public
    property OnMove: TMoveEvent read FOnMove write FOnMove;
  end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    LabeledEdit1: TLabeledEdit;
    LabeledEdit2: TLabeledEdit;
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    procedure LE1Move(Sender: TObject; X, Y: Integer);
    procedure LE2Move(Sender: TObject; X, Y: Integer);
  public
    procedure AfterConstruction; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  TypInfo;

const
  MaxSet = 255; // Largest ordinal value in a Delphi set.

type
  TSet = set of 0..MaxSet;

function SetToString(Info: PTypeInfo; const Value; const Separator, Prefix, Suffix: string): String; overload;
var
  CompInfo: PTypeInfo;
  CompData: PTypeData;
  SetValue: TSet absolute Value;
  Element: 0..MaxSet;
begin
  CompInfo:=GetTypeData(Info)^.CompType^;
  CompData:=GetTypeData(CompInfo);
  Result:='';
  for Element:=CompData.MinValue to CompData.MaxValue do begin
    if Element in SetValue then
      if Result = '' then
        Result := Prefix + GetEnumName(CompInfo, Element)
      else
        Result := Result + Separator + GetEnumName(CompInfo, Element);
  end;
  if Result = '' then
    Result := Prefix + Suffix
  else
    Result := Result + Suffix;
end;

function SetToString(Info: PTypeInfo; const Value; const Separator: string): String; overload;
begin
  Result:=SetToString(Info, Value, Separator, '[', ']');
end;

function SetToString(Info: PTypeInfo; const Value): String; overload;
begin
  Result:=SetToString(Info, Value, ', ');
end;

{ TLabeledEdit }

procedure TLabeledEdit.WMMove(var Message: TWMMove);
begin
  inherited;
  if Assigned(FOnMove) then
    FOnMove(Self, Message.XPos, Message.YPos);
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  LabeledEdit1.OnMove:=LE1Move;
  LabeledEdit2.OnMove:=LE2Move;
end;

procedure TForm1.AfterConstruction;
begin
  inherited;
  Panel2.Height:=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel2.Height:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Panel2.Height:=104;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ShowMessage('LE1 Anchors = ' + SetToString(TypeInfo(TAnchors), LabeledEdit1.Anchors));
  ShowMessage('LE2 Anchors = ' + SetToString(TypeInfo(TAnchors), LabeledEdit2.Anchors));
end;

procedure TForm1.LE1Move(Sender: TObject; X, Y: Integer);
begin
  Label1.Caption:=Format('LE1 pos: %d : %d', [X, Y]);
end;

procedure TForm1.LE2Move(Sender: TObject; X, Y: Integer);
begin
  Label2.Caption:=Format('LE2 pos: %d : %d', [X, Y]);
end;

end.

// dfm
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 304
  ClientWidth = 643
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 200
    Top = 56
    Width = 31
    Height = 13
    Caption = 'Label1'
  end
  object Label2: TLabel
    Left = 200
    Top = 96
    Width = 31
    Height = 13
    Caption = 'Label2'
  end
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 185
    Height = 304
    Align = alLeft
    TabOrder = 0
    ExplicitLeft = 152
    ExplicitTop = 96
    ExplicitHeight = 41
    DesignSize = (
      185
      304)
    object Panel2: TPanel
      Left = 1
      Top = 81
      Width = 183
      Height = 104
      Anchors = [akLeft, akTop, akRight, akBottom]
      Constraints.MaxHeight = 104
      TabOrder = 0
      DesignSize = (
        183
        104)
      object LabeledEdit1: TLabeledEdit
        Left = 8
        Top = 24
        Width = 121
        Height = 21
        Anchors = [akLeft, akRight, akBottom]
        EditLabel.Width = 61
        EditLabel.Height = 13
        EditLabel.Caption = 'LabeledEdit1'
        TabOrder = 0
      end
      object LabeledEdit2: TLabeledEdit
        Left = 48
        Top = 72
        Width = 121
        Height = 21
        Anchors = [akLeft, akRight, akBottom]
        EditLabel.Width = 61
        EditLabel.Height = 13
        EditLabel.Caption = 'LabeledEdit2'
        TabOrder = 1
      end
    end
  end
  object Button1: TButton
    Left = 200
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Hide'
    TabOrder = 1
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 281
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Show'
    TabOrder = 2
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 200
    Top = 140
    Width = 75
    Height = 25
    Caption = 'Anchors'
    TabOrder = 3
    OnClick = Button3Click
  end
end


如果在创建表单后Panel2.Height未设置为0,则在调整表单大小时,编辑将上下移动。如果在窗体创建时Panel2.Height设置为0,则编辑在Panel2中保持不可见,如果显示Panel2,则它们保持不可见,从而Top位置为负。

有人可以帮忙吗?

最佳答案

两种可能的解决方案:


在表单的Panel2事件中而不是在OnShow中将AfterConstruction的高度设置为零,或者
Panel2将另一个面板放在Align=alBottom上。


我不知道第一个解决方案为何有效的确切原因,但是它肯定有优点,因为在OnCreate(或您使用的AfterConstruction)期间,尚未分配窗口控件句柄。

关于delphi - anchor [akLeft,akRight,akBottom]无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15093331/

10-10 01:40