none
C# メニュー選択で画面表示を切り替える方法 RRS feed

  • 質問

  •  メニュー選択でフォーム(WindowsForm)の画面表示を切り替えるにはどうすれば良いですか?動作としては、タブコントロールに近いのですが、タブコントロールのタブで切り替えるのでは無くメニュ選択で切り替えたいです。

    質問1 タブコントロールを使用する方法について
     メニューのClickイベントをタブコントロールと連動させることはできますが、不要になった上部のでっぱり(タブ表示)を消す方法が分かりません。

    質問2 複数のフォームを作成し、Hide()/Show()で切り替え表示する方法について
     切り替え部分をどう記述すればエレガントになりますか?

    質問3 質問1、質問2の以上に推奨できる実装方法があれば教えてください。

    宜しくお願いします。


    C#開発者
    2010年8月10日 6:48

回答

  • もう少し詳細な仕様がわからないと何を推薦(紹介)して良いのかわかりませんが、書かれているメニューがアプリケーションのメインのメニューだとすれば、MDIという選択もあります。WindowsFormはその内部で動的に切り替えてWindowsFormを表示できませんので、MDIとして実装するか、複数のフォームを切り替えるしかないと思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答の候補に設定 山本春海 2010年8月24日 8:24
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    2010年8月10日 7:05
    モデレータ
  • > 質問3 質問1、質問2の以上に推奨できる実装方法があれば教えてください。

    推奨までいきませんが、こういう方法もあるということで。

    ちょっと変わった設計ですが、アプリケーションに Form を一つしか設けず、メニューや業務の流れに応じて、 表示するUserControl を切り替えるという案件がありました。
    Form をコンテナとしか機能させず、業務処理を全て UserControl に任せてしまうというものです。

    その時はこんな方法もあるのかと感心したものですが、自分が設計するならこの手法は用いないかも。

     

     


    ひらぽん http://d.hatena.ne.jp/hilapon/
    • 回答の候補に設定 山本春海 2010年8月24日 8:25
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    • 回答としてマークされていない MicroVAX 2010年9月2日 10:02
    • 回答としてマーク MicroVAX 2010年9月2日 10:02
    2010年8月10日 7:39
    モデレータ
  • 私も MDI をイメージしました。ただ、MDI にしてしまうと幾つかの MDI らしい動作をしてしまうため、それらが気に入らない場合には、ひらぽんさんが書かれているような UserControl による実装が手軽だと思います。その場合は、よくインストーラー等で表示されるような、手順をおって画面が遷移していくタイプの雛型が、"Wizard" などで検索するとゴロゴロ出てくると思います。

    他の方法として私が用いることがあるのは、ApplicationContext の派生クラスを作成することです。
    通常の WinForms アプリケーションだと、Application.Run に対して ApplicationContext を与えないため、標準の ApplicationContext が使用されます。この ApplicationContext は「最初のフォームが閉じるとアプリケーションが終了する」というものですが、ApplicationContext を派生して動作をカスタマイズできます。
    ここで「最初のフォームが閉じると、2番目のフォームを表示する。2番目のフォームが閉じると、閉じた条件にあわせて3番目のフォームが表示されたり、最初のフォームが表示される。3番目のフォームが閉じたらアプリケーションは終了する。」といったフォーム遷移のロジックを実装することができます。
    フォーム切替のタイミングで Show/Hide の順序を調整すると、まるで中身が入れ替わったように見せることもできます。(エフェクトとか追加されてるとばればれですが...)

    • 回答の候補に設定 山本春海 2010年8月24日 8:25
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    • 回答としてマークされていない MicroVAX 2010年9月2日 10:02
    • 回答としてマーク MicroVAX 2010年9月2日 10:03
    2010年8月10日 7:56
  • メニュー選択が「menuStripコントロール」を指すならば、みなさんの仰っている通りMDIで実現可能です。

    フォームにmenuStripコントロール」を配置し、フォームの「IsMDIContainer」プロパティをTrueにします。

    http://dobon.net/vb/dotnet/form/mdiapplication.html

     

    Hide()/Show()で切り替えとありますが、Hide()した後にShow()すれば、当然Hide()する前の画面の状態

    で再表示される感じになりますので、もし画面の内容を初期化する必要がある場合は、そのコードを

    実装する必要があるかと思います。

    また、多くのフォームをHide()Show()することで、それぞれのフォームオブジェクトは非表示になっている

    だけで破棄はされていませんので、メモリをその分消費することにもなります。

    画面の仕様上、実行される環境、また想定しうるHide()されるフォーム数のボリューム的に

    この方法で問題ないか確認する必要があるかと思います。

     

    なお、毎回各画面を初期化して開く感じであれば、Hide()ではなく、フォームの破棄でよいと思います。

    前回の内容を保持して再表示する必要があればHide()が簡単ですが、上記を検討してみてください。

    • 回答の候補に設定 山本春海 2010年8月24日 8:25
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    • 回答としてマークされていない MicroVAX 2010年9月2日 10:01
    • 回答としてマーク MicroVAX 2010年9月2日 10:02
    2010年8月10日 8:26
  • こんにちは、MicroVAX さん。

    MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。

    みなさんからのレスポンスはご確認いただけましたでしょうか。
    投稿いただきましたみなさん、情報ありがとうございます。

    参考になると思われる投稿に、勝手ながら私のほうで回答としてマークさせていただきました。

    解決に役立った投稿や、参考になった情報など、有効な情報には回答としてマークすることをお願いしています。
    今後、同じ問題でこのスレッドを参照される方にも、有効な情報がわかりやすくなるかと思いますので、よろしくお願いいたしますね。

    他にも、この件で情報をお持ちの方は、是非投稿をお願いいたします。それでは。
                                                               
    マイクロソフト株式会社 フォーラム オペレーター 山本 春海

    • 回答としてマーク MicroVAX 2010年9月2日 10:01
    2010年9月2日 6:07

すべての返信

  • もう少し詳細な仕様がわからないと何を推薦(紹介)して良いのかわかりませんが、書かれているメニューがアプリケーションのメインのメニューだとすれば、MDIという選択もあります。WindowsFormはその内部で動的に切り替えてWindowsFormを表示できませんので、MDIとして実装するか、複数のフォームを切り替えるしかないと思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答の候補に設定 山本春海 2010年8月24日 8:24
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    2010年8月10日 7:05
    モデレータ
  • > 質問3 質問1、質問2の以上に推奨できる実装方法があれば教えてください。

    推奨までいきませんが、こういう方法もあるということで。

    ちょっと変わった設計ですが、アプリケーションに Form を一つしか設けず、メニューや業務の流れに応じて、 表示するUserControl を切り替えるという案件がありました。
    Form をコンテナとしか機能させず、業務処理を全て UserControl に任せてしまうというものです。

    その時はこんな方法もあるのかと感心したものですが、自分が設計するならこの手法は用いないかも。

     

     


    ひらぽん http://d.hatena.ne.jp/hilapon/
    • 回答の候補に設定 山本春海 2010年8月24日 8:25
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    • 回答としてマークされていない MicroVAX 2010年9月2日 10:02
    • 回答としてマーク MicroVAX 2010年9月2日 10:02
    2010年8月10日 7:39
    モデレータ
  • 私も MDI をイメージしました。ただ、MDI にしてしまうと幾つかの MDI らしい動作をしてしまうため、それらが気に入らない場合には、ひらぽんさんが書かれているような UserControl による実装が手軽だと思います。その場合は、よくインストーラー等で表示されるような、手順をおって画面が遷移していくタイプの雛型が、"Wizard" などで検索するとゴロゴロ出てくると思います。

    他の方法として私が用いることがあるのは、ApplicationContext の派生クラスを作成することです。
    通常の WinForms アプリケーションだと、Application.Run に対して ApplicationContext を与えないため、標準の ApplicationContext が使用されます。この ApplicationContext は「最初のフォームが閉じるとアプリケーションが終了する」というものですが、ApplicationContext を派生して動作をカスタマイズできます。
    ここで「最初のフォームが閉じると、2番目のフォームを表示する。2番目のフォームが閉じると、閉じた条件にあわせて3番目のフォームが表示されたり、最初のフォームが表示される。3番目のフォームが閉じたらアプリケーションは終了する。」といったフォーム遷移のロジックを実装することができます。
    フォーム切替のタイミングで Show/Hide の順序を調整すると、まるで中身が入れ替わったように見せることもできます。(エフェクトとか追加されてるとばればれですが...)

    • 回答の候補に設定 山本春海 2010年8月24日 8:25
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    • 回答としてマークされていない MicroVAX 2010年9月2日 10:02
    • 回答としてマーク MicroVAX 2010年9月2日 10:03
    2010年8月10日 7:56
  • メニュー選択が「menuStripコントロール」を指すならば、みなさんの仰っている通りMDIで実現可能です。

    フォームにmenuStripコントロール」を配置し、フォームの「IsMDIContainer」プロパティをTrueにします。

    http://dobon.net/vb/dotnet/form/mdiapplication.html

     

    Hide()/Show()で切り替えとありますが、Hide()した後にShow()すれば、当然Hide()する前の画面の状態

    で再表示される感じになりますので、もし画面の内容を初期化する必要がある場合は、そのコードを

    実装する必要があるかと思います。

    また、多くのフォームをHide()Show()することで、それぞれのフォームオブジェクトは非表示になっている

    だけで破棄はされていませんので、メモリをその分消費することにもなります。

    画面の仕様上、実行される環境、また想定しうるHide()されるフォーム数のボリューム的に

    この方法で問題ないか確認する必要があるかと思います。

     

    なお、毎回各画面を初期化して開く感じであれば、Hide()ではなく、フォームの破棄でよいと思います。

    前回の内容を保持して再表示する必要があればHide()が簡単ですが、上記を検討してみてください。

    • 回答の候補に設定 山本春海 2010年8月24日 8:25
    • 回答としてマーク 山本春海 2010年9月2日 6:07
    • 回答としてマークされていない MicroVAX 2010年9月2日 10:01
    • 回答としてマーク MicroVAX 2010年9月2日 10:02
    2010年8月10日 8:26
  • こんにちは、MicroVAX さん。

    MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。

    みなさんからのレスポンスはご確認いただけましたでしょうか。
    投稿いただきましたみなさん、情報ありがとうございます。

    参考になると思われる投稿に、勝手ながら私のほうで回答としてマークさせていただきました。

    解決に役立った投稿や、参考になった情報など、有効な情報には回答としてマークすることをお願いしています。
    今後、同じ問題でこのスレッドを参照される方にも、有効な情報がわかりやすくなるかと思いますので、よろしくお願いいたしますね。

    他にも、この件で情報をお持ちの方は、是非投稿をお願いいたします。それでは。
                                                               
    マイクロソフト株式会社 フォーラム オペレーター 山本 春海

    • 回答としてマーク MicroVAX 2010年9月2日 10:01
    2010年9月2日 6:07