2011-06-23 58 views
5

假設我的表單A包含一個面板(其中包含許多其他控件)和一個表單B,它是空的。
我可以以編程方式從窗體A分離面板並將它移動到窗體B中(也可以回到窗體A)?如何分離面板並將其顯示在單獨的窗口中?

我知道我可以更改面板的所有者,但它可以在不同的窗體之間工作嗎?

更新:
一些谷歌搜索後,我看到有一個ParentWindow屬性。

+0

'ParentWindow'不起作用。請參閱文檔中的[this](http://docwiki.embarcadero.com/VCL/en/Controls.TWinControl.ParentWindow):「如果Parent不是零(Delphi)或NULL(C++),則設置ParentWindow不起作用。」 '父'不是零(它是formA)。 –

回答

2

您可以輕鬆擁有的東西看起來好像它是一個面板,也可作爲一種形式,通過真正使用TForm的什麼你會使用的面板。然後在運行時將表單停靠在爲此目的而留有空白麪板的位置,並以相同的方式在運行時取消它。

您無法取消鎖定TPanel並將其作爲頂級窗體顯示,但您可以採用頂級窗體並將其停靠在代碼中。要獲得所需的外觀和功能,必須使用正確的工具(本例中爲TForm)。

順便說一下,像Toolbar 2000這樣的組件庫允許基於工具欄面板的浮動工具欄窗口,所以如果你真的堅持讓所有的designtim元素保持一種形式,在設計時,你應該看看它在Toolbar 2000它有很多代碼可以使工具欄處於「未鎖定/浮動」模式,並且可以處理鼠標驅動的工具欄停靠和取消鎖定到工具欄停靠欄。

2

如果在運行時創建的面板和子組件,你可以設置面板的ParentFormB

Panel1.Parent := FormB; 

注意FormB有你可以做到這一點之前已經創建成功了。

欲瞭解更多信息,請參閱德爾福維基頁面here

+0

這僅適用於面板未在form A上創建designtime的情況,否則面板A將擁有該面板的所有權。 – NGLN

+0

同意。編輯以反映這一點。 –

+0

不幸的是,控制面板的配置非常複雜。在運行時建立它們將是相當繁重的工作。 – Ampere

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例程以從面板的所有子控件中移除所有權。

請注意,面板的子控件目前沒有所有者。但由於它們是面板的父控制,所以面板的銷燬將釋放這些控制。所以要確保面板有父母,或者明確地釋放面板。

以上所有僅適用於設計時創建的面板,將設計時間放在窗體上,這是我的假設。由於這種變化的父母行爲顯然是需要或需要的,所以您可能需要考慮在運行時完全實現它。爲了保持設計面板設計時間的能力,我建議創建一個框架,您可以在該框架上設計該面板,並在窗體周圍跳轉框架。

+0

其實,你不太對。更改父母更改誰將其銷燬(父母的職責 - 請參閱我在答案中發佈的文檔鏈接)。因此,更改父處理從Form1中刪除該組件並將其添加到Form2。 (這是特別描述在我鏈接的wiki條目 - 請參閱** Note **。) –

+0

@Ken Parent是Owner,是從D7開始的某個地方介紹的嗎? – NGLN

+0

@NGLN:其實我不確定。我沒有再安裝D7,無法檢查。這是在XE,我只是檢查了D2010,它是一樣的。我將無法在稍後檢查D2007。 –

8

正如其他人所指出的,有幾個問題,改變控制的父窗口不改變所有權,並改變一個老闆控制是很困難的,如果它有多個控件坐在上面......

一解決方法是使用一個框架。一個框架擁有它所有的子控件,所以你需要做的就是改變框架的所有者和父母,其他的東西都會隨之而來。這種方法還允許您將所有事件處理程序和代碼粘貼到一個地方。

N - [

+0

+1爲了解釋_why_幀是最好的解決方案。顯然,我不知道如何用我的建議來管理。 ;-) – NGLN

相關問題