gpt4 book ai didi

delphi - 动态创建的框架中的控件对齐问题

转载 作者:行者123 更新时间:2023-12-03 15:30:17 27 4
gpt4 key购买 nike

我的程序使用动态创建的框架,有时我会遇到它们的控件未正确对齐的问题。

我使用自己的从TPanel继承的容器控件,但在使用GridPanel时也会发现同样的问题。

这是 test 的来源重现问题的程序(带有已编译的 exe)。

关键代码片段:

在主窗体中:

//creating Frame from the main form
procedure TForm1.FormCreate(Sender: TObject);
begin
f := TFrame2.Create(Self);
f.Parent := Self;
end;

在框架中:

//constructor of the Frame
constructor TFrame2.Create(AOwner: TComponent);
begin
inherited;
Edit1.Clear;// the problem appears
end;

框架及其所有控件均已对齐,并且必须具有主窗体的宽度,但 Edit1ComboBox1 在视觉上并未对齐,除非您手动调整窗体大小(发送 WM_SIZE 无效)。

但是,如果您注释 Edit1.Clear 行,则从程序开始一切都会正常工作。此代码并非特定于错误,您可以在此处输入,例如ComboBox1.Items.Add('')

如果框架是静态创建的,或者将 GridPanel 更改为 Panel,问题就会消失。

我做了一个新的test2版本感谢@quasoft,它工作得更好 - 现在控件水平对齐正确,但垂直组合框不在正确的位置,可以通过更改表单大小看到。

最佳答案

快速修复:

解决问题的快速方法是使用 TEditText 属性,而不是 Clear 方法 - 正如已经说过的,替换 Edit1.ClearEdit1.Text := ''.

理解问题

但是如果您打算长期使用 Delphi 中的框架,您需要更好地理解这个问题,否则它们会在您 sleep 时困扰您(开玩笑)。

真正的问题是您在为框架分配Parent 之前修改了框架的状态。

procedure TForm1.FormCreate(Sender: TObject);
begin
f := TFrame2.Create(Self); // <--- Your text edit is cleared inside
f.Parent := Self; // <--- Your frame is attached to the form here
end;

这样做不允许 TGridPanel 组件在计算其列和行的大小时考虑父级的宽度、高度和位置。

使用 Text 属性是有效的,因为属性 setter 不会直接更改控件的文本,而是为此目的向消息队列发送一条消息:

Except from Controls.pas:

...
procedure TControl.SetTextBuf(Buffer: PChar);
begin
Perform(WM_SETTEXT, 0, Longint(Buffer));
Perform(CM_TEXTCHANGED, 0, 0);
end;

procedure TControl.SetText(const Value: TCaption);
begin
if GetText <> Value then SetTextBuf(PChar(Value));
end;
...

实际上,在您分配框架的Parent之后,这会导致文本实际发生变化 - 因为消息队列将在表单创建方法完成后稍微处理一下。

另一方面,

Clear 方法直接更改文本:

Excerpt from StdCtrls.pas:

...
procedure TCustomEdit.Clear;
begin
SetWindowText(Handle, '');
end;
...

更好的解决方案

正如您所知,快速修复仅适用于您提供的特定示例。

更好的解决方案是在框架中创建一个 Init 方法,并在分配 Parent 后从主窗体调用此方法:

您的框架:

procedure TFrame2.Init;
begin
Edit1.Clear;
ComboBox1.Items.Add('Foo Bar');
end;

您的主表单:

procedure TForm1.FormCreate(Sender: TObject);
begin
f := TFrame2.Create(Self);
f.Parent := Self; // <--- Your frame is attached to the form here
f.Init; // <--- Calls initialization code of frame
end;

关于delphi - 动态创建的框架中的控件对齐问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41909992/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com