我有一个小问题与锚。
我有一个有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
位置为负。
有人能帮忙吗?
4条答案
按热度按时间gtlvzcf81#
两种可能的解决方案:
1.在窗体的
OnShow
事件中而不是AfterConstruction
中将Panel2
的高度设置为零,或者1.将另一个面板与
Align=alBottom
一起放置在Panel2
上。我不知道为什么第一个解决方案 * 确实 * 起作用,但它肯定有优点,因为在
OnCreate
(或您使用的AfterConstruction
)期间,窗口控制句柄还没有分配。gwbalxhn2#
我找到了解决这个问题的方法,但它与锚无关,它与
Align = alCustom
有更多的关系。但是如果有人对我如何解决它感兴趣,这里有一些代码来解释它。
我们需要为
Panel2
处理OnAlignPosition
。就这样
baubqpgj3#
我有同样的问题11.3和修复它禁用此设置:
nmpmafwu4#
锚定控件更喜欢将其锚定位置设置在实际存在的位置。 Delphi 很难在不适合所有控件的空间中安排控件。锚可能会“卡”在错误的位置,相邻对齐的控件可能会意外地交换位置。
当控件所在的面板更改为正大小时,请调整控件的位置,使其位于您希望的位置。只要它们保持可见(即,只要面板没有折叠到零高度),它们的锚将继续将它们保持在正确的位置。