私はパネルが(それに他の多くのコントロールを含む)パネルとそれが空であるフォームBを含むフォームAを持っているとしましょう。
プログラムでパネルをフォームAから切り離し、フォームBで移動することはできますか?パネルを切り離して別のウィンドウに表示するにはどうすればいいですか?
私はパネルの所有者を変更することができますが、それは異なるフォームの間で動作するのですか?
更新:
Google検索の後、私はParentWindowプロパティがあることがわかります。
私はパネルが(それに他の多くのコントロールを含む)パネルとそれが空であるフォームBを含むフォームAを持っているとしましょう。
プログラムでパネルをフォームAから切り離し、フォームBで移動することはできますか?パネルを切り離して別のウィンドウに表示するにはどうすればいいですか?
私はパネルの所有者を変更することができますが、それは異なるフォームの間で動作するのですか?
更新:
Google検索の後、私はParentWindowプロパティがあることがわかります。
@
Nは本当にあなたがパネルを使用しているだろう何のためにTFormのを使用することによって、それがパネルだったかのように、また、フォームとして表示されます。次に、その目的のために空白のパネルが残っている場所に実行時にフォームをドッキングし、同じ方法で実行時にドッキング解除します。
TPanelをドッキング解除してトップレベルフォームウィンドウとして表示することはできませんが、トップレベルフォームウィンドウを使用してコードにドッキングすることができます。必要な外観と機能を得るには、正しいツール(この場合はTForm)を使用する必要があります。
ちなみに、Toolbar 2000のようなコンポーネントライブラリは、ツールバーパネルに基づいてフローティングツールバーウィンドウを可能にするので、designtim要素をdesigtimeで1つのフォームに残すことを本当に強く求めているのであれば、ツールバー2000ツールバーを「ドッキング解除/フローティング」モードで表示したり、ツールバードックへのマウス駆動ドッキングやドッキング解除を処理するためのコードがたくさんあります。
パネルと子コンポーネントが実行時に作成されている場合は、あなただけのFormB
にパネルのParent
を設定することができます。
Panel1.Parent := FormB;
注FormB
は、あなたがこれを行うことができます前に、既に作成されている必要があること。
詳細については、Delphi Wikiページhereを参照してください。
あなたは所有権を考慮する必要があります。そうしないと、フォーム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.InsertedPanel
とPanel1
点が、それは一種の意味的に好適です。たぶん中央制御変数が良いでしょう。
アップデート:私は誤ってRemoveComponentは、パネル上の子コントロールにカスケード接続することを想定し
。もちろん、フォームAからパネルを削除するだけでは、パネルのすべての子コントロールがフォームAによって所有されたままになります。そのため、RemoveComponentsルーチンを追加してパネルのすべての子コントロールから所有権を削除しました。
この時点で、パネルの子コントロールには所有者がいないことに注意してください。しかし、彼らはパネルの親コントロールであるため、パネルを破壊するとそれらのコントロールが解放されます。したがって、パネルに親があるか、パネルを明示的に解放してください。
上記のすべては、デザイン時に作成されたパネルにのみ適用され、フォーム上にデザインタイムが配置されていましたが、それは私の前提でした。この変更された親の動作は明らかに必要とされているか、必要であるため、実行時に完全に実装することを検討することをお勧めします。パネルデザインを設計する能力を維持するために、そのパネルをデザインし、フォームの周りにフレームをジャンプできるフレームを作成することをお勧めします。
実際、あなたは正しくはありません。親を変更すると、誰がそれを破壊するのかが変更されます(親は行います - 答えに投稿したドキュメントのリンクを参照してください)。したがって、Form1からコンポーネントを削除してForm2に追加する処理は、Parentハンドルを変更します。 (それは特に私がリンクしているwikiエントリーに記載されています - **注**を参照してください) –
@Ken親は所有者で、それはD7以来導入されていますか? – NGLN
@NGLN:実際、私はよくわかりません。私はもうD7をインストールしておらず、確認できません。それはXEにあり、私はちょうどD2010をチェックし、それは同じです。私は後日までD2007をチェックすることができません。 –
他の人が指摘したように、所有権を変更することなく、コントロールの親ウィンドウを変更すると、それはそれの上に座って、複数のコントロールを持っている場合はコントロールの所有者が困難なことが変化するにはいくつかの問題がある...
ワン代わりにフレームを使用することです。フレームはすべてのサブコントロールを所有していますので、フレームの所有者と親を変更するだけで済みます。それ以外はすべて一緒に表示されます。このアプローチでは、すべてのイベントハンドラとグルーコードを単一の場所に保持することもできます。あなたは簡単に何かを持つことができます
+1 _why_を説明するためにフレームが最適な解決策です。どうやら私は何とか私の提案でそれをどうにかして管理していませんでした。 ;-) – NGLN
'ParentWindow'は機能しません。ドキュメントの[this](http://docwiki.embarcadero.com/VCL/en/Controls.TWinControl.ParentWindow)を参照してください。 "ParentWindowを設定すると、Parentがnil(Delphi)またはNULL(C++)でない場合は効果がありません。 'Parent'はnilではありません(formAです)。 –