我有一个 AutoSize 为真的面板。
procedure TfrmIntDetails.FormCreate(Sender: TObject);
begin
MyPanel.AutoSize:= true;
end;
其内容在表单OnShow事件中动态显示或隐藏。所以它的高度发生了变化。
procedure TfrmIntDetails.FormShow(Sender: TObject);
begin
Button1InsideMyPanel.visible:= true;
Button2InsideMyPanel.visible:= false;
//MyPanel height is changed but Height property does not updated
PanelHeight:= MyPanel.Height;
end;
我可以在表单完全加载后获得新的高度(如下所示),但问题是它的高度在OnShow事件中没有改变。
procedure TfrmIntDetails.Button1Click(Sender: TObject);
begin
PanelHeight:= MyPanel.Height;
end;
问:我需要一种方法强制MyPanel根据OnShow事件中的内容(例如发布消息)更新其高度。
答案 0 :(得分:2)
要在OnShow
事件中发布消息,您可以使用@ MasonWheeler的delayedAction实现。
它引用了一个匿名过程,并通过PostMessage
调用将其放在Windows消息队列中。
示例:
DelayExec( // Puts an anonymous procedure on the message queue
procedure
begin
PanelHeight := MyPanel.Height;
end
);
幕后是一个用于发布消息的窗口句柄,以及用于删除对匿名过程的额外引用的逻辑。
<强>更新强>
您提到建议的解决方案不起作用。
如果表单上有待处理的绘制操作,那么在更新PanelHeight
属性之前等待它们完成可能是个好主意。
以下是该怎么做:
DelayExec( // Puts an anonymous procedure on the message queue
procedure
var
Msg: TMsg;
begin
// Make sure all pending paint messages are executed
while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
DispatchMessage(Msg);
PanelHeight := MyPanel.Height;
end
);
答案 1 :(得分:1)
尝试使用此代码:
procedure TfrmIntDetails.FormShow(Sender: TObject);
begin
Button1InsideMyPanel.visible:= true;
Button2InsideMyPanel.visible:= false;
//MyPanel height is changed but Height property does not updated
PanelHeight:= MyPanel.Height;
MyPanel.Height:=1; // This forces the panel to auto size
PanelHeight:= MyPanel.Height; // Re check the value and see it has changed (it will be greater than 1 if MyPanel.AutoSize = true)
end;