ドッキング ウィンドウは、DockContentを継承したフォームとして作成します。なおこのクラスは、System.Windows.Forms.Formを継承しています。
ソリューション エクスプローラ上でプロジェクトを右クリックし、[追加]の[新しい項目]を選択します。そして[Windows Forms]のカテゴリから[継承されたフォーム]を選択します。

[継承ピッカー]ウィンドウで継承元コンポーネントを指定し、[参照]をクリックします。

「WeifenLuo.WinFormsUI.Docking.dll」ファイルを開きます。

DLLに含まれるコンポーネントから、[DockContent]を指定します。

これで、DockContentを継承したフォームが作成されます。
public partial class MyDockContent : WeifenLuo.WinFormsUI.Docking.DockContent
{
}
FormやUserControlを継承したコントロールならば、その基本クラスをDockContentに変更するだけです。そうではないならば、そのコントロールを格納するDockContentを作成した上で、そのDockContentをドッキング ウィンドウとして表示します。
private MyControl myControl; private WeifenLuo.WinFormsUI.Docking.DockContent myControlContainer; // コントロールのコンテナ myControlContainer = new WeifenLuo.WinFormsUI.Docking.DockContent(); myControlContainer.Controls.Add(myControl); // コンテナにコントロールを追加 myControlContainer.Show(dockPanel); // コンテナをドッキング可能として表示
DockPanelをShow()の引数に渡して表示することで、それにドッキングできるようになります。逆にDockPanelを指定せずに表示すると、どこにもドッキングできません。
public partial class Form1 : Form
{
private WeifenLuo.WinFormsUI.Docking.DockPanel dockPanel;
private MyDockContent myDockContent;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// dockPanelがMDIの子コントロールではないとき、DocumentStyleが既定のDockingMdiのままDockContentを表示すると、InvalidOperationExceptionとして例外が投げられる
dockPanel.DocumentStyle = DocumentStyle.DockingWindow;
myDockContent = new MyDockContent();
myDockContent.Show(dockPanel);
}
}
DockPanelにテーマが設定されていないと、Show()の呼び出しで「DockPanel.Theme must be set to a valid theme.」としてArgumentExceptionが投げられます。
| メソッド | 機能 |
|---|---|
| void Show(DockPanel dockPanel) | dockPanelにドッキング可能な状態で、設定済みのDockStateで表示
設定済みのDockStateが"Unknown"または"Hidden"だと、「Invalid DockState: Content can not be showed as "Unknown" or "Hidden".」としてArgumentExceptionが投げられる。よってDockStateを指定した方が安全 |
| void Show(DockPanel dockPanel, DockState dockState) | dockPanelにドッキング可能な状態で、指定のdockStateで表示 |
| void Show(DockPanel dockPanel, Rectangle floatWindowBounds) | dockPanelにドッキング可能な状態で、floatWindowBoundsの大きさで、フロートウィンドウとして表示 |
| void Show(DockPane pane, IDockContent beforeContent) | pane区画の、beforeContentより前に表示 |
| void Show(DockPane previousPane, DockAlignment alignment, double proportion) | previousPane区画のalignmentの位置に、proportionの割合だけずらして表示 |
複数のDockContentを同一のDockPanelに表示した場合、後から表示したものが右または下のタブに表示され、最後のものが最初にアクティブになります。
通常とは逆に、前へ追加するには次のようにします。
dockPanel2.Show(dockPanel1.Pane, dockPanel1);
既存のDockContentと同一の区画へ、位置をずらして追加するには次のようにします。
double proportion = 0.5; dockPanel2.Show(dockPanel1.Pane, DockAlignment.Bottom, proportion);
| 追加位置 | 追加方法 |
|---|---|
| 上下左右の同一位置の中の先頭の区画、の末尾 | myDockContent.Show(dockPanel, DockState.DockRight); |
| 指定区画、の先頭 | myDockContent.Show(dockPanel.Pane, dockPanel); |
| 上記以外、の末尾 |
myDockContent.Show(dockPanel, dockPanel.Pane.DockState); myDockContent.Pane = dockPanel.Pane; |
非表示にされたウィンドウをプログラムから表示するには、Show()を呼ぶだけです。しかしAutoHideの状態のウィンドウはタブが表示されるだけのため、表示されたことを視認しづらいです。この問題には、親ウィンドウのActiveAutoHideContentに自身を設定し展開することで対処できます。c# - Calling up DockPanel-Suite's "AutoHidden" DockContent programmatically - Stack Overflow
myDockContent.Show(); if (myDockContent.DockState == DockState.DockTopAutoHide || myDockContent.DockState == DockState.DockBottomAutoHide || myDockContent.DockState == DockState.DockLeftAutoHide || myDockContent.DockState == DockState.DockRightAutoHide) { // アクティブなウィンドウとして設定することで、閉じられた状態を展開させる myDockContent.DockPanel.ActiveAutoHideContent = myDockContent; // 再び閉じられないように、実際にアクティブにする myDockContent.Activate(); }
DockContentはFormを継承していますが、Show()とHide()はnewで隠蔽されているためFormのそれとは動作が異なります。FormではVisibleプロパティを設定するだけであり、このプロパティを直接設定しても同じです。一方でDockContent.Show()はDockHandler.Show()を呼ぶだけであり、それは
public void Show()
{
if (DockPanel == null)
Form.Show();
else
Show(DockPanel);
}
のように実装されているため、ドッキング ウィンドウの親であるDockPanelが設定されているならばShow(DockPanel)が呼び出されます。またDockContent.Hide()はDockHandler.Hide()を呼び、それは
public void Hide()
{
IsHidden = true;
}
であることから、IsHiddenへの設定となります。このときVisibleには設定されないためVisibleChangedは発生せず、DockStateChangedが発生します。
Visibleプロパティはnewで隠蔽されておらずForm.Visibleへの設定と同じため、Formとは異なりShow()とHide()の呼び出しとは異なる結果となります。
引数でDockState.Floatとして表示するとフロート ウィンドウとして表示されますが、
myDockContent.Show(dockPanel, DockState.Float);
そのときのサイズはDockPanelクラスのDefaultFloatWindowSizeプロパティの定義
public Size DefaultFloatWindowSize { get; set; } = new Size(300, 300);
により、300x300に設定されます。これをサイズを指定して表示するにはRectangleを渡して
myDockContent.Show(dockPanel, myDockContent.Bounds);
とします。このオーバーロードは内部でDockState.Floatを引数に取るShow()を呼ぶため、この方法でもフロート ウィンドウとなります。
後で表示するためにドッキングの位置のみを指定するには、Show()を呼ばずプロパティに設定します。たとえば、
myDockContent.Show(dockPanel, DockState.DockRight);
と表示するときの状態を指定するには
myDockContent.DockPanel = dockPanel;
myDockContent.ShowHint = DockState.DockRight;
// myDockContent.Pane = ドッキングする区画
とします。一方で、
myDockContent.Show(previousPane, DockAlignment.Bottom, 0.5);
のように指定区画に表示する場合は
myDockContent.DockPanel = previousPane.DockPanel; myDockContent.Pane = previousPane.DockPanel.Theme.Extender.DockPaneFactory.CreateDockPane(myDockContent, previousPane, DockAlignment.Bottom, 0.5, false);
のようにCreateDockPane()から設定します。
| 型 | プロパティ | 内容 |
|---|---|---|
| bool | AllowRedocking | trueならば、ドラッグアンドドロップによって再びドッキングすることを許可 |
| double | AutoHidePortion | AutoHideモードで表示されるときの表示サイズの割合。有効な数値は0.0~1.0の間で、既定値は0.25 |
| bool | CloseButton | trueならば、[閉じる]ボタンが有効 |
| DockAreas | ドッキング可能な領域 | |
| DockContentHandler | DockHandler | |
| DockPanel | DockPanel | ドッキング ウィンドウの親
これに設定するとウィンドウが表示される。 親が変更されるときにControl.AssignParent()が呼ばれ、それによりVisibleChangedや、FontChangedなどが呼ばれることがある AssignParent - Control.cs |
| DockState | DockState | ドッキング状態 |
| DockState | ShowHint | 初回に表示するときのドッキング位置 |
| DockState | VisibleState | 可視でのドッキング状態。非表示にされる前の状態が保持されている
DockStateプロパティがHiddenに変更されたときは、その前の状態。それ以外ではDockStateと同じ |
| bool | HideOnClose | trueならば、ウィンドウを閉じるように指示されたときに、閉じずに非表示とする |
| bool | IsActivated | trueならば、現在アクティブ |
| bool | IsFloat | trueならば、フロート ウィンドウ。つまりVisibleStateがDockState.Floatである |
| bool | IsHidden | trueならば、非表示
これはDockStateプロパティがHiddenであることを意味していて、タブで他のウィンドウに隠れていたり、AutoHideで隠れていてもtrueとはならない。またUnknownであってもfalseが返されるため、表示されているとも限らない Hide()を呼び出すことは、IsHiddenをtrueとすることと同じ |
| bool | Visible | (Controlから継承) 次の状態のときに、false
|
| DockPane | Pane | 現在の区画 |
| DockPane | PanelPane | ドッキングされる区画 |
| DockPane | FloatPane | フロートでの区画 |
| string | TabText | DockPaneのタブに表示する文字列。これが設定されていない場合は、Textプロパティの値が用いられる |
派生元のFormに対し、追加で実装されているのは下表のイベントのみです。
| 型 | イベント | 発生タイミング |
|---|---|---|
| EventHandler | DockStateChanged | DockStateが変更されたとき |
AutoHideで隠されたり表示されたりすることを通知するイベントはありませんが、そのときウィンドウのサイズが変化することからそれを検知できます。隠されるときにはSizeChangedイベントが2度発生します。上端または下端にドッキングしているときは1度目にHeightだけがゼロとなり、2度目にWidthもゼロとなります。左右の端では、1度目にWidthがゼロとなります。
フォントを基準とした自動スケーリング (AutoScaleMode.Font) を適用しているとき、DockPanelの親フォームのフォントを変更すると、DockContentの子コントロールのスケーリングが正しく処理されないことがあります。そのときには次のいずれかの方法で対処します。
myDockContent = new MyDockContent(); myDockContent.Font = this.Font; myDockContent.Show(panel1, DockState.Float);
PatchController.EnableFontInheritanceFix = falseとして、DockPanelのフォントが子コントロールに波及しないようにするDockPaneのタブのボタンはスケーリングが考慮されていないため、DockPaneを表示後に変更すると不適切に表示されます。c# - Resize dock pane tab strip text and buttons in Document docked DockContent - Stack Overflow
ドッキングした状態からフロートに変更されるとき、Anchorが指定されたコントロールのサイズが、意図せぬ大きさに調整されることがあります。この問題は、サイズがゼロならば基本クラスのOnSizeChanged()を呼ばないようにすることで対処できます。
protected override void OnSizeChanged(EventArgs e)
{
if (!Size.IsEmpty)
{
base.OnSizeChanged(e);
}
}
親ウィンドウが閉じられるときにFormClosedイベントが発生しないならば、ドッキングする側のウィンドウのClose()を明示的に呼ぶようにします。これはDockPanel Suiteのバグであり、DocumentStyleを指定しても解決できません。Documents' FormClosed() event is not fired when DockPanel is closed · Issue #613 · dockpanelsuite/dockpanelsuite · GitHub