Home > C#

WPFでドッキング・ウィンドウの管理、解決する手段を構築する

原文

Building a Docking Window Management Solution in WPF

WPFでドッキング・ウィンドウの管理、解決する手段を構築する

ソースのダウンロード-1.8MB

訳文

WPFでドッキング・ウィンドウの管理、解決する手段を構築する
Building a Docking Window Management Solution in WPF

Ashish Kaila、2011年1月1日

はじめに  Introduction

ウィンドウをドッキングさせることは、マルチウィンドウ・アプリケーションで使い慣れた機能です。 ユーザー・インターフェースの開発者として、この動作は、いつも、私を魅惑しました。 そして、私は、私自身のWPFのツールキットで同じ機能を開発ことについて考えました。 私は、類似の解決策に多くの実装が存在することを知っています。いくつかは、さらにオープンソースです。 しかし、私の目的は、挑戦と学習機会として、この個人的なプロジェクトを捉えることでした。

私は、同様に、私が実装した、私の会社、MixModes Incの下で継続的に構築している、 より大きなWPFのツールキットの一部のドッキングの解決策に言及しています。 しかしながら、私は、それをオープンソースと無償のプロジェクトとして継続するつもりです。 このライブラリの完全な機能を見るために、あなたは、ここにある、私のブログを訪ねることができます。

ウィンドウをドッキングさせる解決策として、多くの既存の実装では、 MDIの親のウィンドウの下で独立したウィンドウとして管理される浮動ウィンドウを持っています。 しかしながら、私は、すぐに、このコードをSilverlightに移植するつもりで、 厳密に、親のウィンドウの中に含まれる浮動ウィンドウを保持し続けました。

私は、同様に、CodePlex上で、このプロジェクトを主催しています。:

Synergyツールキットの解剖  Anatomy of Synergy Toolkit

MixModes Synergyツールキットは、次のトップレベル・プロジェクトで構成されています。:
MixModes.Synergy.Resources
画像と言語リソースが含まれています。
MixModes.Synergy.Themes
ユーザー・コントロール、ユーザー定義したウィンドウ、色、ブラシとテキスト・テーマのための既定のテーマを定義します。
MixModes.Synergy.Utilities
一般的なユーティリティ
MixModes.Synergy.VisualFramework
挙動、装飾、コマンド、ユーザーコントロール、ドッキングフレームワークと他のWPF固有の機能が含まれています
Synergy
ツールキットの機能を強調するサンプル・プロジェクト

ドッキング可能なウィンドウの解剖  Anatomy of Dockable Window

ウィンドウをドッキングさせる解決策を理解するために、それは、そのすべてを動かすとても原始的なコントロールを理解することが必要です
ドッキング可能なウィンドウ。  the dockable window
ドッキング可能なウィンドウは、内容とタイトルに加えて、次に示すいくつかの状態になることができる特別なウィンドウです。:
ピンでとめられた状態  Pinned state
ピンでとめられた状態 Pinned state
ドッキング可能なウィンドウは、整合性がとれた表示属性を持つように、 親のウィンドウの端にピンでとめることができます。 通常、頻繁に使用された内容は、より簡単で一定のアクセスのためにピンでとめられます。
自動で隠れる状態  Auto hidden state
自動で隠れる状態 Auto hidden state
あまり頻繁に使用されないウィンドウは、マウスがその上に覆いかぶさっていないとき、自動的に非表示にすることができます。 それらは、圧縮された形式に折りたたまれます(それは、ヘッダとして参照されます)。 マウスがヘッダに覆い被さるとき、完全なウィンドウは、ドッキング側から外側へスライドします。
ドキュメントの状態  Document state
ドキュメントの状態 Document state
ドキュメントとして使用されるとき、ドッキング可能なウィンドウは、タブ・コントロール内のタブの項目として結合することができます。
浮動 Floating
通常の浮動ウィンドウ
浮動 Floating-通常の浮動ウィンドウ
ドッキングウィンドウのサポートは、HeaderedContentControlから派生した、DockPaneコントロールによって提供されます。 それが、HeaderedContentControlから継承するHeaderとContentプロパティに加えて、それは、同様に、次に示すプロパティが含まれています。:
Icon
ドッキングするウィンドウのためのアイコン
CondencedDockPanelTemplate
圧縮されたDockPaneのためのテンプレート
CondencedDockPanel
DockPaneの圧縮された形式
DockPaneState
ドック枠の状態
DockPaneは、同様に、次に示すイベントが含まれています。:
Close
イベントを閉じます
TogglePin
ピン/オートハイド・ボタンを切り換えます。
HeaderDrag
ユーザーがDockPaneのヘッダ(タイトル)のドラッグを開始したことを通知します。
DockPaneのための既定のテーマは、MixModes.Synergy.Themesプロジェクト内のDockPane.xamlリソース・ディクショナリで定義されています。

ドキュメント・コンテナ  Document Containers

DockPane(s)は、ドキュメント・コンテナ内に含まれます。 ドキュメント・コンテナは、ContentControlから派生したDocumentContainerクラスによってモデル化されます。 DocumentContainerは、次に示す(相互に排他的な)状態の1つであることができます。:
Empty
DocumentContainerは、どんなDockPaneも含むことができません。
ContainsDocuments
DocumentContainerは、ドキュメントとして1つ以上のDockPane(s)が含まれています。
SplitHorizontally
DocumentContainerは、水平に分割されます。
SplitVertically
分割
DocumentContainerは、垂直方向に分割されます。
DocumentContainerは、分割されたビューかタブ付きのビューを表示を必要とする時から、 そのテンプレートに関して複雑になります。私は、テンプレートの中で永続的なTabControlを使用しました。 内容プロパティが、nullでない場合、それは表示されません。 2つの子供たちのDocumentContainerでグリッドに分割したビューが含まれるため、内容は、もちろん、排他的に使用されます。
DocumentContainerは、次に示すプロパティが含まれています。:状態
DocumentContainerの状態
ドキュメント
Containsドキュメントは、TabControlで表示されます
DocumentsTab
TabControlは、ドキュメントが含まれています。
DockIllustrationPanel
DockIllustrationPanel
これは、ユーザーに内容がどこにドッキングするかを示す、ドッキングする位置の図が含まれているパネルです。 ユーザーが、これらの場所のどこかに、DockPaneをドラッグする場合、それは、それぞれの位置にドッキングします。 下の画像は、DockIllustrationPanelの内容を示しています。:
DocumentContainerは、次に示すメソッドが含まれています。:
AddDockPane(DockPane、ContentDockPoint)
ドッキングするウィンドウとしてDockPaneを追加します。
AddDocumentContainers(IEnumerable, bool)
子のDocumentContainersを分割して、追加します。
AddDocument(DockPane)
タブ付きのドキュメントとしてDockPaneを追加します。
RemoveDocument(DockPane)
タブ付きのドキュメントとしてDockPaneを削除します。
DocumentContainerのテンプレートは、レイヤ内に次に示す外観が含まれています。(一番下の外観は、増加しているZオーダーです。):
TabControl(PART_DOCUMENTS)
DocumentContainerのDocumentsプロパティに結び付けられます。
ContentPresenter
これは、分割した子供たちが追加されるところです。
Grid(PART_DOCK_POINTS)
ドック・イラスト・ポイントを受け入れるためのパネル
Grid(PART_DOCK_ILLUSTRATION)
キューを通してDockIllustrationPanelのためにドッキングの見込みを図解します。

Windowsマネージャー  Windows Manager

Windowsマネージャは、アプリケーションでウィンドウ管理機能を提供するために、 DockPanel(s)とDocumentContainer(s)を一緒に結合するコンポーネントです。 加えて、ウィンドウマネージャは、すべての4つのウィンドウ端の上に、オートハイドとピンのドック・ポイントが含まれます。 このように、DockPane(s)は、DocumentContainer(s)の外側にピンでとめるか、自動で隠すことができます。 WindowsManagerは、同様に、ルートDocumentContainerが含まれています。 それは、タブ・コントロールや入れ子にされて分割して受け入れられたドキュメントの DocumentContainerインスタンスの中にドキュメントを受け入れることができます。
WindowsManagerは、次に示す、プロパティを持っています。:
DockPaneIllustrationStyle
WindowsManagerやDocumentsContainerの中でウィンドウをドッキングさせるための図
DockIllustrationContentStyle
TabControlでDockPaneをドラッグしながらドキュメントを結合するための図
ActiveWindowsManager
ドラッグ操作によりWindowsManagerを示す静的プロパティ
DraggedPane
ドラッグされているDockPane
<Orientation>WindowHeaders
スタック・パネルは、圧縮され、自動で非表示にされたDockPane(複数可)が含まれています。
<Orientation>PinnedWindows
DockPanelは、ピンでとめられたDockPane(複数可)が含まれています。
DocumentContainer
ルート・ドキュメント・コンテナ
DockingIllustrationPanel
将来のピンでとめられるDockPanel(複数可)のためのドッキング・イラスト・パネル
PopupArea
マウスが圧縮されたヘッダ上にある時、自動で非表示にされたDockPane(複数可)が外へスライドするDockPanel
FloatingPanel
浮動DockPane(複数可)が含まれているCanvas
DockingPanel
DockPanel
下の画像で示されるように、ピンでとめられたウィンドウのためのドックする場所が含まれている
WindowsManagerは、次に示す、メソッドを持っています。:
AddPinnedWindow(DockPane, Dock)
ピンでとめられたDockPaneを追加します
AddAutoHideWindow(DockPane, Dock)
自動で非表示にされたDockPaneを追加します
AddFloatingWindow(DockPane)
浮動DockPaneを追加します
RemoveDockPane(DockPane)
WindowsManagerからDockPaneを取り除きます(ピンでとめられたか、自動で非表示にされたか、浮動部分)
Clear
WindowManagerからすべてのDockPane(s)を取り除きます
StartDockPaneStateChangeDetection
DraggedPaneのための起動状態監視
StopDockPaneStateChangeDetection
DraggedPaneのための停止状態監視

どのようにすべて一緒に動作するのか How It All Works Together

下に画像は、ドッキングの解決策のさまざまなコンポーネントの間の結び付きを図解します。: コンポーネントの間の結び付き 構造的に、WindowsManagerは、ピンでとめられ、自動で非表示にされたDockPane(複数可)を含む、 それを取り囲んでいるコンポーネントです。それは、同様に、ルートDocumentContainerが含まれています。 一方で、DocumentContainerは、DocumentContentインスタンスの中でDockPaneをラップする、 タブ・コントロールのドキュメント、 あるいは、子のDocumentContainer(s)を格納するグリッドにある分割したウィンドウのどちらかを含むことができます。 ドキュメントや、より遠い子のDocumentContainer(複数可)のどちらかを再帰的に含むことができます。

ドラッグ&ドロップとドッキング機能を組織化するため、私は、動作駆動型のアプローチを使用しています。 発想は、DockPane、DocumentContainerとWindowsManagerと、行動を組み合わせるために使用して、 これらの機能的な終点を呼び出すような、外観の実体の上で(メソッドとプロパティのような)、 機能的な終点を公開することです。この方法は、同様に、追跡、 そして、検証がより簡単に処理できるカプセル化したコンポーネントを結果として生じます。

DockPointBehaviorは、WindowsManagerの上のドラッグされたDockPaneを監視し、 それをピンでとめるためのドックする場所をポップアップします。 一方で、ContentPointBehaviorは、分割とタブ結合する目的で、 DocumentContainerに類似の機能を導入します。

WindowsManagerとDocumentContainerの両方は、ドッキング動作を含む、ドック・イラスト・グリッドを持っています。 DockPointBehaviorの動作は、WindowsManagerの上でピンでとめられたドッキングの図を図解します。 ところが、ContentDockBehaviorは、DocumentContainerの上で分割とタブの結合の図を図解します。

コードを使用する Using the Code

WindowsManagerを使用することは、とても簡単です。:

xmlns:visualFx="http://mixmodes.com/visualFx"

XAMLでWindowsManagerをドロップします:

<sualFx:WindowsManager x:Name="WindowsManager"/ >

DockPaneを作成し開始して、WindowsManager/DocumentContainerの中でそれらを挿入します:

DockPane pane = new DockPane();
pane.Header = …
pane.Content = ….
WindowsManager.AddPinnedWindow(pane, Dock.Top);
// OR
WindowsManager.AddAutoHideWindow(pane, Dock.Left);
// OR
// Assuming DocumentContainer is either in Empty or ContainsDocuments state
// DocumentContainerが空、または、ContainsDocuments状態のどちらかの場合、
WindowsManager.DocumentContainer.AddDocument(pane);

ウィンドウの状態をシリアル化する Serializing Window State

箱から出して、Synergyは、XmlWindowsManagerSerializerとXmlWindowsManagerDeserializerクラスによって、 ウィンドウ状態のXMLシリアル化を提供します。ユーザー定義したシリアル化は、それぞれ、 特化したWindowsManagerSerializerとWindowsManagerDeserializer基底クラスを通してサポートされます。

XmlWindowsManagerSerializerを使用するWindowsManagerのXMLシリアル化は、構築時に2つの情報を必要とします。:
DockPane writer
Action<XmlElement, DockPane>インスタンスは、XmlElementにDockPaneに関する追加のメタデータを記述することができます。
Document writer
Func<DocumentContent, string<インスタンスは、DocumentContentを理解して、内容の文字列表現を返します。
備考:
DocumentContent.DockPaneプロパティは、関連したDockPaneを返します。 しかしながら、 DockPaneのHeaderとContentプロパティは、nullに設定されます。 HeaderとContentプロパティにアクセスするために、 直接、DocumentContentインスタンスのHeaderとContentプロパティを使用します。

一旦、XmlWindowsManagerSerializerインスタンスが作成されると、 Serialize(Stream, WindowsManager)メソッドへの呼び出しは、ストリームに合わせてWindowsManagerをシリアル化します。

シリアル化プロセスに類似して、 逆シリアル化プロセスは、前に保存された文字列表現からDockPaneを逆シリアル化するために、 XmlWindowsManagerDeserializerのコンストラクタ内のAction<DockPane, string<のインスタンスを必要とします。 逆シリアル化は、DocumentContentは、本質的にDockPaneのためのシリアル化ラッパであり、 DocumentContentを実現するために追加のActionを必要としません。

一旦、XmlWindowsManagerDeserializerインスタンスが作成されると、 Deserialize(Stream, WindowsManager)呼び出しは、前に保存した状態にWindowsManagerを逆シリアル化します。

すべてのドッキング機能は、ソースコードでサンプル・アプリ(Synergyプロジェクト)を使用することにより、行うことができます。 どんなコメントや指摘やバグ・レポートは、いつも通り、常に、歓迎します。

楽しいコーディングを!

ライセンス

本記事は、関連したソースコードとファイルとともに、Code Project Open License (CPOL)の下で認可されます。
このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」