如何分离面板并在单独的窗口中显示它?

时间:2011-06-23 23:15:16

标签: delphi vcl

假设我的表格A包含一个面板(其中包含许多其他控件),表格B表示空白。 我可以以编程方式从面板A分离面板并将其移动到表单B(并可能返回到表单A)?

我知道我可以更改面板的所有者但是它可以在不同的表单之间工作吗?

更新:
经过一些谷歌搜索后,我发现有一个ParentWindow属性。

4 个答案:

答案 0 :(得分:8)

正如其他人所指出的,在不改变所有权的情况下更改控件的父窗口存在一些问题,如果控件所有者有多个控件,则更改控件所有者可能会很困难......

一种方法是使用框架代替。一个框架拥有它的所有子控件,所以你需要做的就是改变框架的所有者和父级,其他一切都会随之出现。这种方法还允许您将所有事件处理程序和粘合代码保存在一个位置。

N - [

答案 1 :(得分:4)

你必须考虑所有权,否则表格A的破坏会导致你的小组在B表格上消失(即破坏),或者更糟。

type
  TForm2 = class(TForm)
  public
    InsertedPanel: TControl;  // or TPanel 

procedure RemoveComponents(AForm: TComponent; AControl: TWinControl);
var
  I: Integer;
begin
  for I := 0 to AControl.ControlCount - 1 do
  begin
    if AControl.Controls[I] is TWinControl then
      RemoveComponents(AForm, TWinControl(AControl.Controls[I]));
    if AControl.Controls[I].Owner = AForm then
      AForm.RemoveComponent(AControl.Controls[I]);
  end;
  AForm.RemoveComponent(AControl);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Form2.InsertedPanel := Panel1;
  Panel1.Parent := nil;
  RemoveComponents(Self, Panel1);
  Form2.InsertComponent(Form2.InsertedPanel); // < this is not necessary
  Form2.InsertedPanel.Parent := Form2;        //   as long as Parent is set
  Panel1 := nil;                              //   or if you free the panel
end;                                          //   manually

额外的引用可能看起来有点愚蠢:Form2.InsertedPanelPanel1指向同一个对象,但它在语义上是首选的。也许中央控制变量更好。

<强>更新

我错误地假设RemoveComponent级联到面板上的子控件。当然,它不会只是从表单A中删除面板会使表单的所有子控件仍由表单A拥有。所以我添加了RemoveComponents例程以从面板的所有子控件中删除所有权。 / p>

请注意,面板的子控件目前没有所有者。但由于它们是面板的父级控制,因此面板的破坏将释放这些控件。因此,请确保该面板具有父级,或明确释放该面板。

以上所有内容仅适用于设计时创建的面板,将设计时间放在表单上,​​这是我的假设。由于显然需要或需要更改父项行为,因此您可能需要考虑在运行时完全实现它。为了保持设计面板设计时的可靠性,我建议创建一个框架,您可以在其上设计该面板,并在框架周围跳转框架。

答案 2 :(得分:2)

如果在运行时创建了面板和子组件,您只需将面板的Parent设置为FormB

Panel1.Parent := FormB;

请注意,必须先创建FormB才能执行此操作。

有关详细信息,请参阅Delphi Wiki页面here

答案 3 :(得分:2)

您可以轻松地将某些内容看作是一个面板,也可以作为一个表单,通过真正使用TForm来实现您使用该面板的内容。然后将表单在运行时停靠到为此目的留下空白面板的位置,并在运行时以相同的方式将其取消停靠。

您无法取消停靠TPanel并将其显示为顶级窗体窗口,但您可以使用顶级窗体窗口并将其停靠在代码中。要获得所需的外观和功能,必须使用正确的工具(在本例中为TForm)。

顺便提一下,像Toolbar 2000这样的组件库允许基于工具栏面板浮动工具栏窗口,所以如果你真的坚持让所有的designtim元素保留在一个表单中,那么在设计时你应该看看它在Toolbar 2000中是如何工作的。它有很多代码可以使工具栏处于“未对接/浮动”模式,并处理鼠标驱动的工具栏对接和工具栏对接工具栏。