バージョン

MDI ツールバーのマージ

WinToolbarsManager は、MDI の親フォームおよび子フォームをサポートしています。主な機能を次に示します。

  • 子のツールバー、ツール、およびメニューを、親のツールバー、ツール、およびメニューに自動的にマージします。

  • 自動マージをサポートするためのコードを開発者が記述する必要はありません。

  • 子ツール用のイベント ハンドラを含む、子のツールバー、ツール、およびメニューのアプリケーション コードを、子フォームに完全にカプセル化します。

  • フォームが実際に MDI 子フォームとして使用されているか、スタンドアロンのフォームとして使用されているかに関係なく、子フォーム上のツールバー、ツール、およびメニューが適切に動作します。

  • 複数タイプの子フォームが同じ親の中で共存できます。個々のツールバー、ツール、およびメニューは、それぞれのタイプのフォームがアクティブになるとマージされて表示されます。

  • マージされたツールバー、ツール、およびメニューに対して実行された、エンド ユーザーによるカスタマイズが、別のタイプの子フォームがアクティブ化されたときでも保持されます。

  • エンド ユーザーのカスタマイズに影響を与えることなく、マージされたツールバー レイアウトをプログラムから保存およびロードできます。

  • 親および子のツールが各ツールのキーに基づいてマージされます。このため、異なる子フォーム上にある、論理的に等価なツールを同じツールとして扱うことが可能です。

概要

MDI のシナリオで UltraToolbarsManager を使用するには、MDI 親フォームと、ツールバー、ツール、またはメニューを必要とする各子フォームに、UltraToolbarsManager 要素を配置します。そして、個々の UltraToolbarsManager を通常どおりに(つまり、通常のスタンドアロン フォームであるかのように)設定します。これには、デザインタイム カスタマイザを使用するか、または実行時にツールバー、ツール、またはメニューを動的に作成するコードをフォームに追加します。

ランタイムに MDI 子フォームが作成されてアクティブになると、そのツールバー、ツール、およびメニューが、MDI 親フォームのツールバー、ツール、およびメニューに自動的にマージされます。アプリケーションで MDI の親および子のツールバーが マージされない ようにする場合は、親または子のどちらかの UltraToolbarsManager の MdiMergeable プロパティを False に設定するだけで済みます(デフォルトの設定は True であり、マージを実行するためには親と子の双方のマネージャの設定を True にする必要があります)。

MDI 子フォーム上の UltraToolbarsManager 要素に対してデザインタイムに特別な要件はない

子フォームの UltraToolbarsManager 要素を設定するときに、あらかじめ(つまりデザインタイムに)特定のフォームを MDI 子フォームとして使用することを決めておく必要はありません。.NET Framework では、フォームをデザインタイムに MDI 子フォームとして明示しておく必要はありませんが、これとまったく同様に、UltraToolbarsManager 要素でも、最終的に MDI 子フォームになるフォーム上で使用することをデザインタイムに指定しておく必要はありません。要素を通常どおりに設定するだけで、ランタイムにそのフォームが MDI 子フォームになった時点で(つまり、その MDIParent プロパティが設定された時点で)、MDI の親の UltraToolbarsManager と自動的にマージされます。

その証拠に、ランタイムに同じフォームの複数のインスタンスを作成し、そのうちの一部のインスタンスの MDIParent プロパティを設定して残りを設定しない、ということが可能です。MDIParent プロパティを設定したインスタンスでは、ツールバー、ツール、およびメニューが親にマージされ、設定しなかったインスタンスでは、ツールバー、ツール、およびメニューが直接フォーム上に表示されます。

特定のフォームをランタイムに MDI 子フォームとして使用することがあらかじめわかっている場合には、UltraToolbarsManager のツールバー、ツール、およびメニューに対してキーを割り当てておくこともできます。 この詳細については、後述の「ツールのキーの選択」セクションを参照してください。

ランタイムの動作

ランタイムにフォームの MDIParent プロパティが設定されて(実際に MDI 子フォームとなって)フォームがアクティブになると、フォームのツールバー、ツール、およびメニューが、MDI 親フォームのツールバー、ツール、およびメニューに自動的にマージされます。マージを実行するためのコードを開発者が追加する必要はありません。マージ プロセスでは、親のツールバー、ツール、およびメニューと、アクティブな子フォームのツールバー、ツール、およびメニューとが、それぞれのキー(ツールの場合はツール タイプ)に基づいて比較されます。

  • ツールバーのマージ - MDI 親フォームのツールバーと MDI 子フォームのツールバーが同じキーを持っている場合は、MDI 子フォームがアクティブ化されたときに双方のツールバーの内容が親フォームでマージされます。ただひとつの例外として、MainMenuBars としてマークされているツールバーはキーの一致不一致に関係なくマージされます。

  • メニューのマージ - MDI 親フォームのメニューと MDI 子フォームのメニューが同じキーを持っている場合は、2 つのメニューの MergeType プロパティの設定に応じて、双方の内容が マージされることがあります 。メニューのデフォルトの Merge Type は 'MergeItems' です。これによって、下の「ツールのマージ」で説明している規則に従って親メニューと子メニュー上の個々のツールはマージされます。その他の MergeType としては、Add(追加)、Merge(マージ)、Remove(削除)があります。

親子双方のメニューの MergeType が Default 以外に設定されている場合は、子のメニューの MergeType 設定のほうが優先されます。MergeType プロパティの組み合わせにより、結果的にメニューがマージされる場合は、下の「ツールのマージ」で説明している規則に従って、メニュー上の個々のツールがマージされます。 * ツールのマージ - 親のツールバー上またはメニュー上の個々のツールが子のツールバーまたはメニューとマージされるときは、マージ プロセスによって、各ツールバーまたはメニュー上に「 一致する 」ツールが存在するかどうかが確認されます。ツールが「 一致する 」と見なされるためには、それらのキーとタイプの両方が同じである必要があります。たとえば、親ツールバーと子ツールバーをマージする際に、「Foo」というキーを持つ Button ツールが親ツールバーにあり、「Foo」というキーを持つ Textbox ツールが子ツールバーにある場合、それらは一致するものとは見なされません。しかし、親と子の双方のツールバーに、「Foo」というキーを持つ Button ツールが含まれていれば、それらは一致するものと見なされます。

親ツールと「一致」しない子ツールは、親のツールバーまたはメニューに常にマージされます。親ツールと「一致」する子ツールは、2 つのツールの MergeType プロパティの設定に応じてマージされます。ツールのデフォルトの MergeType は Replace です(例外として、PopupMenuTool は MergeItems というデフォルトの MergeType を持っています)。この設定では、親のツールバー上またはメニュー上のツールを置き換えるために子のツールを使用します(子ツールが親ツールバーに存在しない場合でも追加されます)。その他の MergeType としては、Add(追加)および Remove(削除)があります。

MDI 子フォームから MDI 親フォームへのツールのマージ方法の詳細については、タスクベースのヘルプ トピック 「MergeOrder と MergeType を使用した MDI ツールのマージの制御」を参照してください。

ツールは MergeOrder プロパティを持っています。このプロパティを使用すると、ツールバーまたはメニューで マージされたツールの表示順序を決めることができます。一致順序と視覚的な表示順序の 両方 を決める .NET の MenuItems の MergeOrder プロパティとは異なり、UltraToolbarsManager ツールの MergeOrder プロパティは視覚的な表示順序だけを決める整数です。マージされたツールバーやメニューの中で同じ MergeOrder 値を持つツールは、すべて次のように表示されます。親ツールが元の順序で表示され、その後に子ツールが元の順序で表示されます。続いて、次に最も高い MergeOrder 値を持つツールが同じ規則に従って表示され、以下同様に表示されます。

ツールのキーの選択

MDI の子フォームまたは親フォームで使用する UltraToolbarsManager を設定するときに、ツールにキーを割り当てる場合は、いくつかの事柄について考慮する必要があります。

ツールのキーは、子ツールが親ツールと一致するかどうかを調べるために使用されます。したがって、ツール同士が「論理的に」同じときだけ、双方のツールに対して同じキー値を割り当てます。このことは、異なる MDI 子フォーム上にあるツールにキーを割り当てる場合にも適用されます。

たとえば、Cut、Copy、Paste のツールを [Edit] メニューで定義し、それらを複数の MDI 子フォームに配置するとします。この場合、ツールはそれぞれ同じ論理機能を表現しているので、すべてのフォームで「Cut」、「Copy」、および「Paste」というキーを各ツールに割り当てればよいように思われます。しかし、これらのツールが、各フォームをアクティブ化したときに異なるツールバーやメニューに表示されるようにする場合、つまり、それらがさまざまなコンテキストで操作され、その動作も異なる可能性がある場合には、個々のツールに異なるキーを割り当てる必要があります(「Cut_FormA」、「Cut_FormB」など)。

このようにする理由は、子ツールが親の UltraToolbarsManager にマージされるときに、親の UltraToolbarsManager で特殊な MDIPlaceholderTools が内部的に作成され、管理されるためです。これにより、マージされた子ツールに関するユーザーのカスタマイズ情報が、別の MDI 子フォームがアクティブ化されたときにも保持できるようになります。新しい子フォームがアクティブ化されると、UltraToolbarsManager は親の MDIPlaceholderTools を子ツールに関連付けようとします。これには、新しくアクティブ化された MDI 子フォームにあるツールのうち、MDIPlaceholderTools と同じツールタイプで、かつ同じキーを持つものを探します。そのようなツールが見つかれば、そのツールが表示されます。UltraToolbarsManager の仕様では、親の MDIPlaceholderTool と子ツールが同じツールタイプで同じキーを持っている場合、それらのツールは「論理的に」同じツールであり、表示されます。同じような名前を持つツール同士では、ほとんどの場合、この動作で問題ありません。 この動作が望ましくない場合は、単純にツールのキーを変更してください。

このことを詳しく説明するために、次のことを仮定します。

  • ChildForm_A で、「Edit」というツールバーに「Cut」というキーを持つツールがあります。

  • ChildForm_B で、「Format」というツールバーに「Cut」というキーを持つツールがあります。

  • ChildForm_A のインスタンスを作成してアクティブ化します。

また、親の UltraToolbarsManager でも「Edit」および「Format」というツールバーを定義しているとします。

ChildForm_B のインスタンスを作成してアクティブ化すると、「Format」ツールバーの「Cut」ツールだけでなく、「Edit」ツールバーの「Cut」ツールも表示されます。マージ プロセスでは、「Cut」という名前の子ツールがすでに(ChildForm_A のアクティブ化によって)「Edit」ツールバーにマージされています。 そして、ChildForm_B がアクティブ化されたときに、このツールを表示するかどうかを決めるため、ChildForm_B の UltraToolbarsManager に「Cut」という名前のツールが存在するかどうかが調べられます。この場合はそのようなツールが存在するため(そして両方のツールが同じタイプであるため)、論理的に同じツールであると見なされ、「Edit」メニューの「Cut」ツールが表示されます。このような動作が望ましいかどうかは、アプリケーションの仕様によって異なります。このような動作を避ける場合は、単に「Cut」ツールに別の名前を割り当てます。

上記の例で、親の UltraToolbarsManager に「Edit」および「Format」というツールバーが定義されていない 場合は、上記とは異なり、ChildForm_A と ChildForm_B に存在するよく似た名前の「Cut」ツール同士が 同じであるとは見なされません

エンド ユーザーによるカスタマイズがマージに与える影響

前のセクションで説明したように、ユーザーのカスタマイズ情報は、別の MDI 子フォームがアクティブ化されたときでも、特殊な MDIPlaceholderTools を使用して内部的に追跡されます。この方法の利点を示す例を次に示します。

たとえば、MDI 子フォームに UltraToolbarsManager 要素があり、「Foo」および「Bar」というキーを持つボタンツールが配置されているとします。ここで、ユーザーがこの MDI 子フォームをアクティブ化します。その結果、これらのツールのインスタンスが、「Format」というキーを持つツールバーに配置されたとします(MDI 親フォームの UltraToolbarsManager 要素にはこれらのキーを持つツールやツールバーはないとします)。次に、ユーザーはドッキング領域を右クリックしてランタイムカスタマイザを起動し、これらのツールを「Edit」というキーを持つツールバーにコピー(または移動)します。このツールバーは親フォームの UltraToolbarsManager に対してのみ定義されています。ユーザーはさらに別のツール(親に対してのみ定義されたもの)を MDI 子フォームの「Format」ツールバーにコピー(または移動)します。

ユーザーがフォームを閉じると、その子ツールは非表示になります。そこで、ユーザーが同じ MDI 子フォームの新しいインスタンスをアクティブ化すると、ツールは移動された場所に再び表示されます。これには、親フォームのツールバーやメニューから移動された子ツールと、子フォームのツールバーやメニューから移動された親ツールが含まれます。

また、「Format」というキーの定義されたツールバーと「Foo」および「Bar」というキーを持つボタン ツールがそれぞれ配置された UltraToolbarsManager 要素を含む、別の MDI 子フォームタイプをユーザーがアクティブ化した場合でも、ツールはユーザーが移動した位置に表示されます。これは、UltraToolbarsManager によって、同じタイプ(ボタン、状態ボタン、ポップアップ メニューなど)および同じキーを持つツール同士が「論理的に」同じツールとして扱われるためです。したがって、MDIPlaceholderTools ではユーザーが期待しているとおりにそれらのツールが正しく「フック」されます。

この方法にはもうひとつ利点があります。それは、ユーザーのカスタマイズ情報を完全に保持したまま、親フォームの UltraToolbarsManager 要素の状態をバイナリまたは XML のストリームに簡単に保存し(UltraToolbarManager の SaveAsBinary および SaveAsXML メソッドを使用します)、再びロードして復元(UltraToolbarManager の LoadFromBinary および LoadFromXML メソッドを使用します)できることです。