在OnShow事件中,AutoSize = true的面板的高度不会更改

时间:2014-06-08 05:22:29

标签: delphi vcl

我有一个 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事件中的内容(例如发布消息)更新其高度。

2 个答案:

答案 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;