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

MDIアプリケーションのメニューのマージ

MDIアプリケーションを作成する基本について、こちらで説明しました。ここではメニューのマージに絞って説明します。

MenuStripコントロールの場合

基本的なメニューのマージ

MDIの親フォームと子フォームにMenuStripコントロールがあり、親フォーム内に子フォームが表示されたとき、親フォームのメニューに子フォームのメニューが合成(マージ)されて表示されます。

補足:フォームに複数のメニューがある場合は、Form.MainMenuStripプロパティでメインのメニューを指定します。メインのメニューがマージされます。

どのようにマージされるか、具体的に見てみましょう。下図のように、親フォームのトップメニューにItem1とItem2があり、子フォームのトップメニューにChildItem1があるとき、親フォーム内に子フォームを表示すると、親フォームのトップメニューの末尾にChildItem1が追加されます。

親フォームのメニュー
+
子フォームのメニュー
マージされたメニュー

子フォームに空のメニューが表示されてしまう問題の解決法

子フォームにMenuStripを付けて、親フォームのMenuStripにマージさせる場合、必ず子フォームのMenuStripのVisibleをfalseにしてください。もしtrueのままですと、子フォームのMenuStripの部分に空のメニューが表示されてしまいます。

マージされるメニューの方法の指定

メニューがどのようにマージされるかを決定するのは、ToolStripMenuItemクラスのMergeActionとMergeIndexプロパティです。以下に、MergeActionプロパティに指定できるMergeAction列挙体のメンバと、その値をMergeActionどのようにメニューがマージされるかを一つずつ説明します。

なお以下の説明では、MDIの親フォームにあるメニューの項目(ToolStripMenuItem)を「親項目」、子フォームにあるメニューの項目(ToolStripMenuItem)を「子項目」と記述します。

MergeAction.Append

子項目のMergeActionをAppendにすると、その子項目はメニューの最後に追加されます。この場合、MergeIndexプロパティの値は無視されます。具体的には、上で説明した図のようなマージとなります。

MergeAction.Insert

子項目のMergeActionをInsertにすると、その子項目のMergeIndexで指定された位置に子項目が挿入されます。例えば、子項目のMergeIndexが0であればメニューの先頭に、1であれば2番目の位置に挿入されます。子項目のMergeIndexが親項目の数より多きいときは、メニューの最後に挿入されます。MergeIndexが-1のときは、子項目が表示されなくなります。

先ほどの例で、ChildItem1のMergeActionをInsert、MergeIndexを1にすると、次のようにマージされます。

Insert

MergeAction.Replace

子項目のMergeActionをReplaceにすると、その子項目のMergeIndexで指定された位置にある親項目の代わりに子項目が表示されるようになります。MergeIndexに該当する親項目がなければ(-1の時を含む)、同じTextプロパティを持つ親項目を探して置換します。それも見つからなければ、子項目は表示されません。

先ほどの例で、ChildItem1のMergeActionをReplace、MergeIndexを1にすると、次のようにマージされます。

Replace

MergeAction.Remove

子項目のMergeActionをRemoveにすると、その子項目のMergeIndexで指定された位置にある親項目を消します。子項目も表示されません。Replaceと同様、MergeIndexで見つからなければ、Textプロパティで探します。

先ほどの例で、ChildItem1のMergeActionをRemove、MergeIndexを1にすると、次のようにマージされます。

Remove

MergeAction.MatchOnly

子項目のMergeActionをMatchOnlyにすると、その子項目のMergeIndexで指定された位置にある親項目のサブメニュー(Itemsプロパティに格納されている項目)に、子項目のサブメニューを追加します。子項目自体は表示されません。Replaceと同様、MergeIndexで見つからなければ、Textプロパティで探します。

先ほどの例で、ChildItem1のMergeActionをMatchOnly、MergeIndexを1にすると、次のようにマージされます。Item21とItem22はItem2に元から存在していた項目で、ChildItem11とChildItem12はChildItem1に存在していた項目です。

MatchOnly

MainMenuコントロールの場合

基本的なメニューのマージ

MDIの親フォームと子フォームにMainMenuコントロールがあり、親フォーム内に子フォームが表示されたとき、親フォームのメニューに子フォームのメニューが合成(マージ)されて表示されます。

補足:フォームに複数のメニューがある場合は、Form.Menuプロパティでメインのメニューを指定します。メインのメニューがマージされます。

どのようにマージされるか、具体的に見てみましょう。下図のように、親フォームのトップメニューにMenuItem1とMenuItem2があり、子フォームのトップメニューにChildMenu1があるとき、親フォーム内に子フォームを表示すると、親フォームのトップメニューの末尾にChildMenu1が追加されます。

親フォームのメニュー
+
子フォームのメニュー
マージされたメニュー

マージされるメニューの挿入位置の指定

ChildMenu1の挿入される位置は、MenuItem.MergeOrderプロパティで変更することができます。例えばChildMenu1をMenuItem1とMenuItem2の間に表示するには、

MenuItem1.MergeOrder = 0
MenuItem2.MergeOrder = 2
ChildMenu1.MergeOrder = 1

というように、ChildMenu1のMergeOrderがMenuItem1とMenuItem2のMergeOrderの間に入るようにします。つまり、MergeOrderはメニューがマージされた時のMenuItemの順番となります。

1つのメニューにマージする

MenuItem1とChildMenu1を一つのメニューとして表示するには、MenuItem1とChildMenu1のMergeOrderを同じ値にして、さらに、それぞれのMergeTypeに適当なMenuMerge列挙値を設定します。(MergeTypeのデフォルトはAddのため、何も指定しないと一番初めの例のように追加して表示されます。)

MenuItem1とChildMenu1のMergeOrderが同じ値で、両方のMergeTypeがMergeItemsの時、下図のように合成されます。

MenuItem1とChildMenu1のMergeOrderが同じ値で、MenuItem1のMergeTypeがReplace、ChildMenu1のMergeItemsがMergeItemsの時は、MenuItem1が表示されなくなります。(つまり、MenuItem1がChildMenu1と置換されます。)

さらにMergeTypeがRemoveの場合は、MergeOrderの同じMenuItemがあってもなくても表示されなくなります。下図は、MenuItem1とChildMenu1のMergeOrderが同じ値、両方のMergeTypeがMergeItemsで、さらに、サブメニューのMenuItem11とChildMenu11のMergeTypeをRemoveとした時のものです。

補足:マージされたメニューは、Form.MergedMenuプロパティで取得できます。
  • 履歴:
  • 2007/1/19 「MenuStripコントロールの場合」を追加。

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

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。