C# DockPanelSuite を使った Docking Window アプリの作り方(Form Classを使いまわす編)

これまででレイアウトの保存、読み込みまではある程度できた。
残りの問題、同じ Form クラスを複数個使用した場合のレイアウトの保存、読み込みについて解決する。

次のように、Form2 クラスを「Form2」「Form2Ex」として複数表示する場合を考える。

DockPanelSuite-form-duplicate

レイアウトが保存される際の識別名はフォームのクラス名が使用されているため、この場合 「Form2」と「Form2Ex」の保存データ上での識別名が同じものになってしまう。

この保存時の識別名を取得している部分を乗っ取れば(オーバーライドしてあげれば)別の識別子で保存が可能になる。
実際には次の関数をオーバーライドする。

string DockContent.GetPersistString()

複数表示させる Form(DockContent)の編集


というわけで、 DockContent を継承している Form2 を次のようにいじる。

  • コンストラクタ引数で識別名を指定するように
  • オーバーライドした GetPersistString() で識別名を返すように
public partial class Form2 : WeifenLuo.WinFormsUI.Docking.DockContent
{
    // 識別名から生成
    public Form2(string persistString)
    {
        InitializeComponent();
        PersistString = persistString;
    }

    // 識別名
    public string PersistString { get; private set; }

    // DockPanel で保存するときに使われる識別名を返す関数をオーバーライド
    protected override string GetPersistString()
    {
        return PersistString;
    }
}

メインフォーム Form1 の編集

管理するフォームにを一つ追加して、Form2~Form3 と同じように生成から掃除までを行うようにする。

private Form2 form2ex = null;

少し変わるのは以下の2か所になる。

/* Form2 の生成時に識別名を渡すようにする */

// フォーム達を生成しておく
form2 = new Form2("Form2");
form2.Text = "Form2";
form2.HideOnClose = true; // 閉じられた時に非表示にするだけ

form2ex = new Form2("Form2Ex");
form2ex.Text = "Form2Ex";
form2ex.HideOnClose = true; // 閉じられた時に非表示にするだけ
/* Form2 の判定をクラス名から設定した識別名に変える */

// レイアウト読み込み時の保存名からどのフォームかを判定する処理
private IDockContent GetDockContent(string persistString)
{
    // フォームのクラス名で保存されているのでそれから判定してあげる
    if(persistString.Equals("Form2"))
    {
        return form2;
    }
    else if(persistString.Equals("Form2Ex"))
    {
        return form2ex;
    }
    else if(persistString.Equals(typeof(Form3).ToString()))
    {
        return form3;
    }
    else if(persistString.Equals(typeof(Form4).ToString()))
    {
        return form4;
    }
    return null;
}

これで、Form2 が使いまわせるようになる。他にも使いまわす Form があるなら同様にする。

最後に

DockPanelSuite の簡単な使い方は以上となる。細かい設定などはかなり端折ったがこれくらいの手順があればとっかかりとしては十分なはず?

ウィンドウのドッキング、フローティングはうまく使うとユーザビリティが良くなったりするので、使う価値は十分あると思う。

以上