web-dev-qa-db-ja.com

Panel.Dock Fillは、他のPanel.Dock設定を無視します

フォーム上にパネルを作成してDock = Topに設定し、別のパネルをドロップしてDock = Fillに設定すると、最初のパネルを無視してフォーム全体に表示される場合があります。タブの順序を変更しても何も起こりません。

142
Jeff Cuscutis

ドッキングレイアウトは、兄弟コントロールのorderに依存します。コントロールは「ボタンアップ」でドッキングされるため、コレクション内の最後のコントロールが最初にドッキングされます。ドッキングされたコントロールは、以前ドッキングされた兄弟のレイアウトのみを考慮します。したがって、他のドッキングされたコントロールを考慮したい場合、Dock = Fillの制御は兄弟順序の最初(上)にある必要があります。これは最初のコントロールではなく、以前のコントロールがオーバーラップします。

兄弟の順序は必ずしも視覚的な順序と同じではなく、兄弟の順序はデザインビューから必ずしも明らかではないため、これは混乱を招く可能性があります。

ドキュメントアウトラインウィンドウ([表示]-> [他のウィンドウ]-> [ドキュメントアウトライン])を使用すると、コントロールの階層と順序のツリービューが表示され、コントロールの兄弟順序を変更できます。

コンテキストメニューで兄弟の順序を直接変更することもできます-> [最前面に移動/最背面に移動]を選択すると、兄弟の最初または最後にコントロールが移動します。実際の効果はレイアウトモデルに依存するため、これらのメニューラベルはやや紛らわしいかもしれません。

位置が固定されたコントロールでは、2Dの位置は兄弟の順序に依存しませんが、コントロールが重なっている場合、順序の最初のコントロールが「上」になり、兄弟の一部が後の順序で非表示になります。このコンテキストでは、最前面に移動/最背面に移動するのが理にかなっています。

フローまたはテーブルレイアウトパネル内では、作成順序によってコントロールの視覚的な順序が決まります。重複するコントロールはありません。したがって、最前面への移動/最背面への移動は、コントロールの順序で最初または最後に作成することを意味します。

ドッキングレイアウトでは、ドッキングを計算する順序を決定するため、最前面への移動/最背面への送信はさらに混乱する可能性があります。そのため、フィルドッキングされたコントロールの「前面に移動」すると、コントロールがmiddle親の、すべてのEdge-dockedコントロールを考慮します。

311
JacquesB

Dock = Fillのパネルを右クリックして、「前面に移動」をクリックします。

これにより、このコントロールが最後に作成され、同じコンテナ内の他のコントロールのDock設定が考慮されます。

103
Jeff Cuscutis

別の潜在的にクリーンなオプションは、TableLayoutコントロールを使用することです。上部のドックに希望する高さの1行を設定し、下部に100%を埋める別の行を設定します。内部の両方のパネルを塗りつぶしに設定すると、完了です。

(ただし、TableLayoutは慣れるまでに時間がかかります。)

7
John Rudy

私は同じ問題を抱えており、なんとか解決できました。
DockStyle.Fillを含むコンテナがある場合、他のコンテナもDockStyleであるがTopまたは必要なものを持っている必要があります。
重要なことは、最初にControlsにDockStyle.Fillのコントロールを追加してから、他のコントロールを追加することです。

例:

ComboBox cb = new ComboBox();
cb.Dock =  DockStyle.Top;

GridView gv = new GridView();
gv.Dock =  DockStyle.Fill;

Controls.Add(gv); // this is okay
Controls.Add(cb);

しかし、cbを最初に置くと

Controls.Add(cb);
Controls.Add(gv); // gv will overlap the combo box.

コード内の要素の順序を変更したくない場合は、Containerを例としてContainer.Controls.SetChildIndex()メソッドを使用できます。フォーム、パネルなど、コントロールを追加します。

例:

     //Container ------------------------------------
     Panel Container = new Panel();

     //Top-Docked Element ---------------------------
     ButtonArea = new FlowLayoutPanel();
     Container.Controls.Add(ButtonArea);
     Container.Controls.SetChildIndex(ButtonArea, 1);
     ButtonArea.Dock = DockStyle.Top;

     //Fill-Docked Element --------------------------
     box = new RichTextBox();
     Container.Controls.Add(box);
     Container.Controls.SetChildIndex(box, 0); //setting this to 0 does the trick
     box.Dock = DockStyle.Fill;
1
Marcus

JacquesBにはドキュメントのアウトラインに関するアイデアはありましたが、階層によって問題が解決しませんでした。私のコントロールは、同じ親とともにリストされた階層スタイルではありませんでした。

順序を変更すると、見た目が変わることがわかりました。

リストの下部のコントロールは、ドキュメントアウトラインウィンドウのリストの上部のコントロールと重なります。あなたの場合、最初のパネルが2番目のパネルの下にあることを確認します。

1
RANONO

私は同じ問題に遭遇しました。私は、実行中にメニューストリップの下に新しい/カスタムコントロールを追加しました。問題は、ドッキング時のコントロールであり、フォームの上部からドッキングすることを決定し、メニューストリップを完全に無視することにしました。これは、デザインモードではなくコードで動的に実行する必要があったため、非常にイライラさせられました。私が見つけた最も簡単な方法は、デザインモードでパネルを作成し、メニューストリップの下にドッキングすることです。そこからコントロールをパネルに追加/削除するだけで、実行時にドッキングできます。本当に変更する必要のないフォーム上のすべてのコントロールを台無しにする必要はありません。本当に必要なことによっては、あまりにも多くの作業が必要になります。

object.dock = Fill
Panel.Controls.Add(object)
0
Robert S.

ここに私のために働いたトリックがあります。

Topアイテムを配置し、上にドッキングします。

Splitterを配置し、上にドッキングし、無効に設定します(上部のサイズを変更する場合を除く)。

次に、Fillオブジェクトを配置し、DockingをFillに設定します。オブジェクトはスプリッターの下に留まります。

0
John Christman

私はこれが古い投稿であることを知っていますが、何か有用なものを発見しました。動的に作成されたコントロールの兄弟コントロールの順序をプログラムで調整するには、次のようなことができます。

parentForm.Controls.SetChildIndex (myPanel, 0) 

私の場合、Dock/Fillパネルを移動してフォームの最初のコントロールにし、Dock/Top(メニューストリップ)に設定された別のドッキングコントロールと重ならないようにしました。

0
DrLechter