DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

MDIアプリケーションを作成する

ここではMDI(マルチドキュメントインターフェイス、multiple-document interface)アプリケーションを作成する上で必要な基本的な知識を一通り説明します(メニューのマージンに関しては、こちらで説明します)。なお、MDIが何かついては、「Windows フォームのレイアウト オプション」等をご覧ください。

MDIの親となるフォーム(以下「親フォーム」)を作成するには、フォームを作成し、IsMDIContainerプロパティをTrueにするだけです。

MDIの子となるフォーム(以下「子フォーム」)を作成するには、フォームを作成し、MdiParentプロパティに親フォームを指定します。そして、子フォームをShowメソッドで表示すれば、親フォーム内に子フォームが表示されます。

MDI子フォームを表示する具体的なコードを示します(親フォームのクラス内に記述します)。ここではすでに親フォームのIsMDIContainerプロパティがTrueになっているものとし、新たに作成したChildFormフォームを親フォームに追加して、表示しています。

VB.NET
コードを隠すコードを選択
'子フォームとするフォームを作成する
Dim frm As New ChildForm
'親フォームをこのフォームにする
frm.MdiParent = Me
'子フォームを表示する
frm.Show()
C#
コードを隠すコードを選択
//子フォームとするフォームを作成する
ChildForm frm = new ChildForm();
//親フォームをこのフォームにする
frm.MdiParent = this;
//子フォームを表示する
frm.Show();

ちなみに、親フォームを閉じると、子フォームも閉じられます。この時、親フォームのClosingイベントが発生する前にすべての子フォームのClosingイベントが発生し、さらに、親フォームのClosedイベントが発生する前にすべての子フォームのClosedイベントが発生します。

アクティブな子フォーム

現在アクティブなMDI子フォームを取得するには、Form.ActiveMdiChildプロパティを使います。子フォームが現在存在しない場合、ActiveMdiChildプロパティはnull(VB.NETではNothing)を返します。

また、アクティブな子フォームが変わった(あるいは無くなった)時、親フォームでMdiChildActivateイベントが発生します。

さらに、子フォームをアクティブにするには、子フォームのActivateメソッドを呼び出します。

親フォームから指定した子フォームをアクティブにするためのメソッドとして、Form.ActivateMdiChildメソッドがありますが、これはprotectedメンバであり、ヘルプによると、「このメンバは、.NET Framework インフラストラクチャのサポートを目的としています。独自に作成したコード内で直接使用することはできません。」とのことです。

下のコードは、アクティブな子フォームのタイトルを親フォームのタイトルに表示するものです。親フォームのタイトルが、「(子フォームのタイトル) - (アプリケーションの名前)」となるようにしています。このコードは親フォームに書かれており、親フォームのMdiChildActivateイベントハンドラがParentForm_MdiChildActivateであるものとします。

VB.NET
コードを隠すコードを選択
'親フォームのMdiChildActivateイベントハンドラ
Private Sub ParentForm_MdiChildActivate( _
    ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles MyBase.MdiChildActivate
    'アクティブな子フォームのタイトルを親フォームのタイトルに追加する
    If Not (Me.ActiveMdiChild Is Nothing) Then
        Me.Text = Me.ActiveMdiChild.Text + " - " + Application.ProductName
    Else
        Me.Text = Application.ProductName
    End If
End Sub
C#
コードを隠すコードを選択
//親フォームのMdiChildActivateイベントハンドラ
private void ParentForm_MdiChildActivate(object sender, EventArgs e)
{
    //アクティブな子フォームのタイトルを親フォームのタイトルに追加する
    if (this.ActiveMdiChild != null)
        this.Text = this.ActiveMdiChild.Text + " - " +
            Application.ProductName;
    else
        this.Text = Application.ProductName;
}
補足:.NET Framework 1.0では、子フォームのActivatedイベントが発生しません。代わりにEnterイベントや、親フォームのMdiChildActivateイベントを使用してください。1.1以降ではActivatedイベントが使えます。

子フォームをすべて取得

MDI親フォーム内のすべての子フォームは、Form.MdiChildrenプロパティで取得できます。

次のコードでは、子フォームをすべて閉じています。(親フォームに記述されているものとします。)

VB.NET
コードを隠すコードを選択
Dim frm As ChildForm
For Each frm In Me.MdiChildren
    frm.Close()
Next frm
C#
コードを隠すコードを選択
foreach (ChildForm frm in this.MdiChildren)
{
    frm.Close();
}

子フォームの整列

子フォームを整列させるには、Form.LayoutMdiメソッドに適当なMdiLayout列挙体の値を指定します。MdiLayout列挙体のメンバには次のようなものがあります。

メンバ名 簡単な説明 ヘルプでの説明と図
ArrangeIcons アイコンの整列

すべての MDI 子アイコンは、MDI 親フォームのクライアント領域内に並べて表示されます。

ArrangeIcons

Cascade 重ねて表示

すべての MDI 子ウィンドウは、MDI 親フォームのクライアント領域内に重ねて表示されます。

Cascade

TileHorizontal 上下に並べて表示

すべての MDI 子ウィンドウは、MDI 親フォームのクライアント領域内に水平に並べて表示されます。

TileHorizontal

TileVertical 左右に並べて表示

すべての MDI 子ウィンドウは、MDI 親フォームのクライアント領域内に垂直に並べて表示されます。

TileVertical

VB.NET
コードを隠すコードを選択
'重ねて表示
Me.LayoutMdi(MdiLayout.Cascade)

'上下に並べて表示
Me.LayoutMdi(MdiLayout.TileHorizontal)

'左右に並べて表示
Me.LayoutMdi(MdiLayout.TileVertical)

'アイコンの整列
Me.LayoutMdi(MdiLayout.ArrangeIcons)
C#
コードを隠すコードを選択
//重ねて表示
this.LayoutMdi(MdiLayout.Cascade);

//上下に並べて表示
this.LayoutMdi(MdiLayout.TileHorizontal);

//左右に並べて表示
this.LayoutMdi(MdiLayout.TileVertical);

//アイコンの整列
this.LayoutMdi(MdiLayout.ArrangeIcons);

子フォームのリストをメニューに表示する

MainMenuコントロールの場合

現在開いている子フォームのリストをメニューに表示させるには、MenuItem.MdiListプロパティをTrueにします。MenuItem.MdiListプロパティをTrueにすると、そのメニュー項目のサブメニューとして子フォームのリストが表示されます。メニュー項目にサブメニューがすでに追加されている時は、末尾にセパレータとリストが追加されるようです。

下図は、「ウィンドウ」MenuItemのMdiListプロパティをTrueにしたときのものです。

MenuStripコントロールの場合

MenuStripのMdiWindowListItemプロパティにリストを表示させるToolStripMenuItemを設定します。例えば、フォームに"MenuStrip1"というMenuStripが配置されており、MenuStrip1に"WindowsListToolStripMenuItem"というToolStripMenuItemが追加されているときに、WindowsListToolStripMenuItemに子フォームのリストを表示するには、次のようにします。

VB.NET
コードを隠すコードを選択
'WindowsListToolStripMenuItemに子フォームのリストを表示する
MenuStrip1.MdiWindowListItem = WindowsListToolStripMenuItem
C#
コードを隠すコードを選択
//WindowsListToolStripMenuItemに子フォームのリストを表示する
MenuStrip1.MdiWindowListItem = WindowsListToolStripMenuItem;

下の図では、「WindowsList」となっているメニュー項目が、"WindowsListToolStripMenuItem"です。

MdiWindowListItemに設定できる項目は、トップメニューだけのようです。MdiWindowListItemに指定したメニュー項目にサブメニューがすでに追加されている時は、末尾にセパレータとリストが追加されます。

  • 履歴:
  • 2007/1/18 「子フォームのリストをメニューに表示する」で「MenuStripコントロールの場合」を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。