Home > C# > Toolkit > DockingWindow > AvalonDock > ドキュメント

AvalonDock1.3入門チュートリアル

原文

AvalonDock 1.3 Getting Started Tutorial(外部サイト)

訳文

AvalonDock1.3入門チュートリアル

AvalonDock 1.3 Getting Started Tutorial

AvalonDockに対するご関心をお寄せいただきありがとうございます。このチュートリアルは、.NET4をターゲットとするAvalonDockバージョン1.3に適用されます。 多くの概念が、最新のリリースに関連している場合であっても、あなたは、どんな、より以前のバージョンへの一般的な案内書としても、本記事を使用することができます。

VisualStudio、あるいは、Expression Blendのような、高度なインターフェースを構築するために、AvalonDockを使用することができます。 それは、自動で隠れる枠、浮動する枠、保存・復元レイアウトのような機能を持っています。そして、それは、同様に、WinFormsコントロールを受け入れることができます。

Main menu:

  • Let's Start!
  • Contents
  • Layout Serialization
  • Sample Project Sources

AvalonDockがどのように動作するか、正しく、理解するために、そのコンポーネントを説明し初めましょう。:

AvalonDock

DockingManager

これは、AvalonDockの中心的なコントロールです。 それは、含まれた枠を配置します。飛び出した枠と浮動ウィンドウを処理します。 上記の画像のDockingManagerオブジェクトは、上部のツールバーから底のステータス・バーまで、 ( WPF用語の)すべてが含まれています。DockingManagerクラスは、 さらに、レイアウトの保存と復元を処理します。

ResizingPanel

このパネルは、それらの間で(Orientationのプロパティで選択する)方向に沿って、寸法変更機能を追加し、枠の子を配置します。 上記のResizingPanelでは、水平方向に3つの枠(:DockablePaneは左側に、DocumentPaneは中央部に、DockablePaneは右側に)を配置しています。

DockablePane

このコントロール( ItemsControl)は、ManagedContentオブジェクトのコレクションが含まれています。 通常、それは、タブ・コントロールのような内容を配置します。上記の、スクリーン・ショットで示されるDockablePanesは、 左側の『Strumenti』と『Progetti』(英語では、ToolとProject )のコンテナ、 そして、右側の『Classi』と『Proprieta』(英語では、ClassとProperty )のコンテナに含まれる内容です。DockablePaneは、自動で非表示にすることができます。 (『Errori』(エラー)、『Lista Azioni』(動作リスト)と『Uscita』(出力)のような内容が、含まれています。) そして、フローティング・ウィンドウのDockingManagerの上にドラッグすることができ、親のDockingManagerの境界線に固定することができます。

DocumentPane

この形式の枠は、通常の文書(DocumentContent型のオブジェクト)を収容していますが、 オプションとして、上記の『ツール』や『クラス』の内容のように、さらに、DockableContentsオブジェクトを収容することができます。 上記の文書内容は、中央部にある、先ほど述べたDockablePaneオブジェクトの間のResizingPanelの中で(水平方向に)配置されます。 文書枠は、移動することができません。

DockableContent

ドッキング可能な内容は、アプリケーション・コントロールのコンテナです。 それは、常に、枠の中に収容されています(DockablePaneまたはDocumentPane)

上のスクリーンショットでは、DockableContentオブジェクトは、『classi』(クラス)オブジェクトです (それは、SharpDevelopオブジェクトに含まれます。)、『strumenti』(ツール)オブジェクトだけでなく、 さらに『Errori』(エラー)も(それは、AutoHidden状態で、自動で隠れる枠に含まれています)。 名前で示唆されるようにDockableContentは、そのコンテナ枠から離れてドラッグすることができ、 他の存在する枠に、あるいは、DockingManagerの親の境界線やフローティング・ウィンドウの左に再配置することができます。

DocumentContentは、DocumentPaneだけで、受け入れることができる内容です。それは、境界線に固定できない特別な内容です。 しかし、実際に、DocumentPaneに配置することができます。 AvalonDockの最新のリリースでは、DocumentContentは、同様に、浮動ウィンドウとしてドラッグすることができます。 しかし、親のDockingManagerに再配置されるとき、それは、常に、DocumentContentの内部に配置される必要があります。 上記のDocumentContentオブジェクトは、『program.cs』または『MainForm.cs』ファイルです。

FloatingWindow

それは、DockingManagerの上にドラッグされるか、移動されるときの内容を含むウィンドウです。 FloatingWindowは、Windowから派生します。そして、常に、枠が含まれています(DockablePaneまたはDocumentPane) それが、1つ以上の内容が次々に含まれています。(DockableContentまたはDocumentContent)。 ユーザーが、内容やDockablePaneのためにドラッグ操作を開始するとき、 FloatingWindowオブジェクトは、常に、DockingManagerから、直接、作成されます。

Pane

それは、DockablePaneとDocumentPaneの基底クラスです。それは、両方のために一般的なプロパティとメソッドを提供します。

ManagedContent

それは、DockableContentとDocumentContentの基底クラスです。それは、両方のために一般的なプロパティとメソッドを提供します。

では、わたしたちのはじめのAvalonDockアプリケーションを作成してみましょう。新しい、Visual Studio2010/SharpDevelop4アプリケーションを作成します。 あなたが、インストーラでAvalonDockをインストールした場合、あなたは、すでに、あなたの環境のTool枠の中で、AvavlonDockコントロールを見ています。 問題が生じた場合、実際に、AvalonDockアセンブリに参照(AvalonDock.dllとAvalonDock.Themes.dll)を追加します。

最初に行うことは、DockingManagerコントロールを追加することです。:


<Window x:Class="AvalonDockSampleProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="24"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="24"/>
        </Grid.RowDefinitions>
        <Menu>
            <MenuItem Header="File">
                <MenuItem Header="Exit"/>
            </MenuItem>
        </Menu>

        <ad:DockingManager x:Name="dockManager" Grid.Row="1"/>
        
        <StatusBar Grid.Row="2">
            <StatusBarItem Content="AvalonDock 1.3 Sample Project"/>
        </StatusBar>
    </Grid>
</Window>

私は、同様に、ウィンドウを、実際に、『飾り立てる』ために、メニューとステータス・バーを追加しています。:)。 今、寸法変更パネルとDockablePane( とDockableContent内側)を追加するレイアウトの作成を開始します。 そして、DocumentPane( とDocumentContent):


        <ad:DockingManager x:Name="dockManager" Grid.Row="1">
            <ad:ResizingPanel Orientation="Horizontal">
                <ad:DockablePane>
                    <ad:DockableContent x:Name="classesContent" Title="Classes"/>
                </ad:DockablePane>
                <ad:DocumentPane>
                    <ad:DocumentContent Title="MyDocument!"/>
                </ad:DocumentPane>
            </ad:ResizingPanel>
        </ad:DockingManager>

または、コード内で、:


public MainWindow()
{
    InitializeComponent();

    var resPanel = new ResizingPanel() { Orientation = Orientation.Horizontal };
    var dockPane = new DockablePane() { };
    var documentPane = new DocumentPane() { };

    dockPane.Items.Add(new DockableContent()
    {
        Name = "classesContent",
        Title = "Classes"
    });

    documentPane.Items.Add(new DocumentContent()
    {
        Title = "My Document!"
    });

    resPanel.Children.Add(dockPane);
    resPanel.Children.Add(documentPane);
    dockManager.Content = resPanel;
}

内容の名前を設定することが重要なことに、ご注意ください。これは、なぜなら、それが、DockingManagerが、格納されたレイアウトを読み込むとき、 正しく内容を識別するために使用されます。名前と内容がなければ、それは、復元しません。 あなたは、私が、DockableContentのために名前を設定するのを見ることができます。 (私は、それを、正しくシリアル化したい)、そして、DocumentContentではなく(他の場合では、私は、レイアウトに保存したくありません)。

今、あなたが、アプリケーションを実行する場合、あなたは、寸法変更機能、自動で隠れる枠を浮遊させて移動し、境界線に固定することができるべきです。 DocumentContentは、代わりに、単純に、メイン・ウィンドウの上を移動し、それがあったところに再配置できます。

次に、より多くの内容とツリー状のモデル内に寸法変更パネルを追加し、レイアウトを少し複雑にしてみましょう。:


        <ad:DockingManager x:Name="dockManager" Grid.Row="1">
            <ad:ResizingPanel Orientation="Vertical">
                <ad:ResizingPanel Orientation="Horizontal">
                <ad:DockablePane ad:ResizingPanel.ResizeWidth="150">
                    <ad:DockableContent x:Name="classesContent" Title="Classes">
                        <TreeView>
                            <TreeViewItem Header="Class1"/>
                            <TreeViewItem Header="Class2"/>
                        </TreeView>
                    </ad:DockableContent>
                    <ad:DockableContent x:Name="toolsContent" Title="Tools">
                        <ListBox>
                            <ListBoxItem Content="Tool1"/>
                            <ListBoxItem Content="Tool2"/>
                            <ListBoxItem Content="Tool3"/>
                        </ListBox>
                    </ad:DockableContent>
                </ad:DockablePane>
                <ad:DocumentPane>
                    <ad:DocumentContent Title="MyDocument!"/>
                </ad:DocumentPane>
            </ad:ResizingPanel>
                <ad:DockablePane ad:ResizingPanel.ResizeHeight="100">
                    <ad:DockableContent Title="Errors" x:Name="errorsContent">
                        <ListView>
                            <ListView.View>
                                <GridView>
                                    <GridView.Columns>
                                        <GridViewColumn Header="Error"/>
                                        <GridViewColumn Header="Page"/>
                                        <GridViewColumn Header="File"/>
                                        <GridViewColumn Header="Row"/>
                                    </GridView.Columns>
                                </GridView>
                            </ListView.View>
                        </ListView>
                    </ad:DockableContent>
                    <ad:DockableContent Title="Output" x:Name="output">
                        <TextBox IsReadOnly="True" AcceptsReturn="True"/>
                    </ad:DockableContent>
                </ad:DockablePane>
            </ad:ResizingPanel>
        </ad:DockingManager>

私が、ドッキング可能な枠の大きさを固定するために、依存関係プロパティ(ResizePanel.ResizingWidth/Height)を使用したことに注意して下さい。 このプロパティの形式(GridLenght)の1つは、パネル大きさを指定することができます。 そして、それは、ユーザーが、リサイザーをドラッグする時、実際に、標準規格Gridパネル内で発生し寸法が変更されます。

現在、あなたは、このような何かを見ているはずです。:

パネル

AvalonDock Content

次に、私たちは、動的に内容を作成する方法を見ることになります。(DocumentContentとDockableContent )。どちらのクラスも、一般的なプロパティとメソッドで定義される、ManagedContentと呼ばれる抽象クラスから派生します。

内容を作成することは、実際に簡単です。:

DocumentContent:


var documentContent = new DocumentContent();
documentContent.Title = "MyNewContent";
documentContent.Show(dockManager);

DockableContent:

var dockableContent = new DockableContent()
 {
    Name = "mynewContent",
    Title = "New Dock Content!"
 };

 dockableContent.Show(dockManager);

ManagedContentとその派生クラスは、Show関数のいくつかのオーバーロードを持っています。 それは、特定の位置と状態の内容を、適切に表示するために使用することができます。 同様に、DockableContentは、DocumentContentと同じくらい、多くのメソッドを持っています。 それは、自動で非表示にする親の枠を使用したり、浮動するウィンドウを表示したりできます。 もちろん、1つは、同様に、それに新しい内容を追加するために、適切な枠を見つけて、DockingManagerの内容を横切ることができます。 このメソッドも、動作します。通常は、いずれにしろ、常に、DockableContent/DocumentContent状態を処理するために、 Show/Hide/Closeのような、標準メソッドを使用するためによく考えます。 これは、なぜなら、DockablePane/DocumentPaneは、DockingManagerの内側を、ユーザーが、内容を移動/固定するように、作成/破壊します。

下記は、Content ans枠に対して使用できる一般的なメソッドの一覧を表示します。:

メソッド

説明

DocumentContent.Show(DockingManager)

DockingManagerで提供されたメイン文書枠の中に文書を表示します。 渡すマネージャーがいない場合、文書の内容が、すでにDockingManager内に含まれていることを確認してください。 DocumentContent.Show ( DockingManager、bool showAsFloatingWindow )Show()メソッドと同様ですが、 しかし、最後のパラメータは、コントロールを呼び出すコードを提供します。あるいは、新しい文書でなければ、浮動するウィンドウを表示します。

DocumentContent.Close()

文書を閉じます(OnClosing/OnClosedイベントが、発生します)。

DocumnetContent.Hide()

Close()メソッドと同じ。

DockableContent.Show(DockingManager)

提供されたDockingManager内に、ドッキング可能な内容を示します。 確実に渡すマネージャーがいない場合、その内容は、すでにDockingManager内にあります。 内容が、隠された状態の場合、(すなわち、内容が、隠されています。)

このメソッドは、先ほどのコンテナ枠の中に位置して、再びそれを表示します。 その枠が、これ以上利用できない場合、右側の枠は、その場で作成されます。 内容が、AutoHidden状態の場合、自動で非表示にされた枠で示された内容は、 アンカー・タブの上にユーザーがマウスを移動するとき発生するように示されます。 DockableContent.Show(desideredAnchor)それをコンテナDockingManagerの境界線に、固定している内容を示します。 枠が、正しいアンカーを見つけた場合、DockingManagerは、それに新しい内容を追加することになります。

DockableContent.ShowAsDocument()

文書などの内容を示します。すなわち、それは、メインの文書枠に追加されます。 そして、その状態を、DockableContentState.Documentに設定します。

DockableContent.ShowAsFloatingWindow()

内容は、浮動するウィンドウの中に表示されます。最後のパラメータ(dockableWindowフラグ)は 、新しいウィンドウが、親のDockingManagerに再びドッキングできる場合を示しています。

DockableContent.Hide()

内容が、隠されます。その状態を、DockableContentState.Hiddenに設定します。 この内容が、再び、表示される場合、DockingManagerは、先ほどのコンテナ枠に、それを追加しようと試みます。 (先程の位置で)DockableContent.Close(bool forceClose)DockableContent.IsCloseableプロパティが、false(既定)である場合、 内容は閉じておらず、単に隠されています(Hide()メソッドを呼び出すのと同じ効果)。 後者の場合には、それは、コントロール・ツリーから取り除かれます。 そして、それは、DockingManager.DockableContentsリストの下には、もはや存在しません。 forceCloseがtrueの場合、IsCloseabledの状態は、考慮されません。

DockableContent.ToggleAutoHide()

内容が、すでに自動非表示の状態である場合、 (DockableContentState.AutoHidden)、それは、親コンテナにドッキングします。 代わりに、それが、ドッキング状態の場合、(DockableContentStated.Docked) それは、フライアウト・ペインに追加され、そして、アンカー・タブは、相対的な境界線に作成されます。

ManagedContent.Activate()

ManagedContentは、DockableContentとDocumentContentの親クラスです。 このメソッドは、それにフォーカスを与えるドッキング・マネージャーの範囲内で、内容を選択します。

以下は、DockableContentが持つことができる状態のリストです。(DocumentContentは、よく似たプロパティを持っていません):

状態

説明

DockableContentState.None

内容は、どんなDockingManagerとも関連付けられていません。

DockableContentState.Docked

内容は、DockingManager内の枠の内側に配置されます。この状態は、最も一般的です。

DockableContenState.AutoHide

枠の内側の内容は、マウスを、DockingManagerの境界線に配置される、小さなラベル(アンカー・タブ)の上に移動して、その場で表示することができます。

DockableContentState.DockableWindow

内容は、次々に浮動するウィンドウの内側の枠の内側にあります。この状態の内容は、境界線やドッキング・マネージャーの枠の中にドッキングすることができます。 (すなわち、アンカーは、ユーザーがウィンドウを動かすように、表示されます)。

DockableContentState.FloatingWindow

内容は、親のDockingManagerにドッキングできない、枠、そして、浮動するウィンドウの内側にあります。(すなわち、それは、通常のウィンドウです)

DockableContentState.Document

内容は、DocumentPaneに含まれています。

DockableContentState.Hidden

内容は、隠されていますが、常に、DockingManager.DockableContentsコレクションに存在します。(備考:この動作は、バージョン1.3に固有のものです)。

レイアウト・シリアル化

Layout Serialization

この最初のチュートリアルの最後の作業は、レイアウトをドッキングさせるためのシリアル化の支援を追加することです。レイアウトを保存します。 単純に、DockingManager.SaveLayout()を呼び出し、復元するメソッドは、同様に、他のメソッドRestoreLayout()を呼び出すように簡単なことを表しています。


const string LayoutFileName = "SampleLayout.xml";

private void SaveLayout(object sender, RoutedEventArgs e)
{
    dockManager.SaveLayout(LayoutFileName);
}

private void RestoreLayout(object sender, RoutedEventArgs e)
{
    if (File.Exists(LayoutFileName))
        dockManager.RestoreLayout(LayoutFileName);
}

たとえそれが、レイアウトを保存・復元することが簡単であるとしても、あなたは、1つか2つの状況に注意を払う必要があります。 まず、あなたは、あなたが保存・復元を必要とする、それぞれの内容のためにNameプロパティを指定する必要があります。 同様に、あなたは、AvalonDockが、どのように、いくつかの特別な場合を処理するかについて知っている必要があります。 例についてよく考えます。あなたは、ただ1つの内容が含まれる初めのレイアウトで、アプリケーションの読み込みを開始します。 その後、いくつかのコマンドをもつ、あなたのユーザーは、新しい内容を追加します (多くの場合、アプリケーションが、実行時に、アドインを読み込むことができる場合です。)。 ユーザーが、アプリケーションを閉じると、あなたのコードは、それを再現するために、 現在のレイアウトを保存する、DockingManager.SaveLayout()を呼び出します。 アプリケーションが、再び立ち上げられる、そして、AvalonDockが、2つの内容を正しく格納するとき、 (1つは、はじめのスタートアップで存在し、そして、1つは、ユーザーが実行時に作成します)。 次に、あなたのユーザーは、アプリケーションを再起動します。 AvalonDockが、現在、そのレイアウトに存在しない内容を見つけるとき、何が発生するのでしょうか? この事例のために、あなたは、特別なコールバック・メソッドを取り扱う必要があります。:


DockingManager.DeserializationCallback(DeserializationCallbackEventArgs);

このメソッドは、DockingManagerが、内容を復元するために見つけることができないときはいつでも呼び出されます。 あなたが、思い出す場合、わたしたちのサンプルでは、私たちは、実行時に、ドッキング可能な内容を追加するために、関数を追加しました。 『mynewContent』と呼ばれます。以下は、そのコールバックメソッドを処理し、新しいドッキング可能な内容を返します。 (もちろん、あなたの場合では、あなたは、アドインのような、あなたが必要なものを、その場で、再現することができます。):


dockManager.DeserializationCallback += (s, e) =>
{
   //asserts that content that docking manager is looking for
   //is mynewContent
   //ドッキング・マネージャーが探している内容がmynewContentであると主張します
   Debug.Assert(e.Name == "mynewContent");

   var dockableContent = new DockableContent()
   {
       Name = "mynewContent",
       Title = "New Dock Content!"
   };

   //returns this new content 
   // この新しい内容を返します
   e.Content = dockableContent;
};

再度、あなたが望む場合について考えます。(常に、アドイン管理の例は、先に説明しました。) あなたが、実行時に、ユーザーに、異なるレイアウトの1つの間を切替えるための機能を与えたいそれは、 単に、1つの内容(最初の)ともう1つ(現在の)が含まれています。それは、2つの内容が含まれています。 (アドインの内容が含まれています)。あなたが、初期レイアウトからアドインレイアウトにレイアウトを変更する場合、 コールバックは呼び出されます。そして、あなたは、動的にアドインを作成する機会を持っています。 あなたが、代わりに初期レイアウトを復元すると、AvalonDockは、ただ1つの内容のレイアウトを復元します。 (それが、初期レイアウトに存在します)。何が、アドインの内容に起こったのでしょう?それは隠されています! これは、あなたが、実際に、それに再び表示するために、 そのDockableContent.Showメソッドを、呼び出す必要があることを示しています。

参考:Sample Project Sources(外部サイト)

adospaceにより、May 28, 2010 at 10:21 PMに、最後に編集されました。バージョン19

このエントリーをはてなブックマークに追加

Home PC C# Illustration

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