トップ回答者
C# メニュー選択で画面表示を切り替える方法

質問
-
メニュー選択でフォーム(WindowsForm)の画面表示を切り替えるにはどうすれば良いですか?動作としては、タブコントロールに近いのですが、タブコントロールのタブで切り替えるのでは無くメニュ選択で切り替えたいです。
質問1 タブコントロールを使用する方法について
メニューのClickイベントをタブコントロールと連動させることはできますが、不要になった上部のでっぱり(タブ表示)を消す方法が分かりません。質問2 複数のフォームを作成し、Hide()/Show()で切り替え表示する方法について
切り替え部分をどう記述すればエレガントになりますか?質問3 質問1、質問2の以上に推奨できる実装方法があれば教えてください。
宜しくお願いします。
C#開発者
回答
-
もう少し詳細な仕様がわからないと何を推薦(紹介)して良いのかわかりませんが、書かれているメニューがアプリケーションのメインのメニューだとすれば、MDIという選択もあります。WindowsFormはその内部で動的に切り替えてWindowsFormを表示できませんので、MDIとして実装するか、複数のフォームを切り替えるしかないと思います。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/ -
> 質問3 質問1、質問2の以上に推奨できる実装方法があれば教えてください。
推奨までいきませんが、こういう方法もあるということで。
ちょっと変わった設計ですが、アプリケーションに Form を一つしか設けず、メニューや業務の流れに応じて、 表示するUserControl を切り替えるという案件がありました。
Form をコンテナとしか機能させず、業務処理を全て UserControl に任せてしまうというものです。その時はこんな方法もあるのかと感心したものですが、自分が設計するならこの手法は用いないかも。
ひらぽん http://d.hatena.ne.jp/hilapon/ -
私も MDI をイメージしました。ただ、MDI にしてしまうと幾つかの MDI らしい動作をしてしまうため、それらが気に入らない場合には、ひらぽんさんが書かれているような UserControl による実装が手軽だと思います。その場合は、よくインストーラー等で表示されるような、手順をおって画面が遷移していくタイプの雛型が、"Wizard" などで検索するとゴロゴロ出てくると思います。
他の方法として私が用いることがあるのは、ApplicationContext の派生クラスを作成することです。
通常の WinForms アプリケーションだと、Application.Run に対して ApplicationContext を与えないため、標準の ApplicationContext が使用されます。この ApplicationContext は「最初のフォームが閉じるとアプリケーションが終了する」というものですが、ApplicationContext を派生して動作をカスタマイズできます。
ここで「最初のフォームが閉じると、2番目のフォームを表示する。2番目のフォームが閉じると、閉じた条件にあわせて3番目のフォームが表示されたり、最初のフォームが表示される。3番目のフォームが閉じたらアプリケーションは終了する。」といったフォーム遷移のロジックを実装することができます。
フォーム切替のタイミングで Show/Hide の順序を調整すると、まるで中身が入れ替わったように見せることもできます。(エフェクトとか追加されてるとばればれですが...) -
メニュー選択が「menuStripコントロール」を指すならば、みなさんの仰っている通りMDIで実現可能です。
フォームに「menuStripコントロール」を配置し、フォームの「IsMDIContainer」プロパティをTrueにします。
http://dobon.net/vb/dotnet/form/mdiapplication.html
Hide()/Show()で切り替えとありますが、Hide()した後にShow()すれば、当然Hide()する前の画面の状態
で再表示される感じになりますので、もし画面の内容を初期化する必要がある場合は、そのコードを
実装する必要があるかと思います。
また、多くのフォームをHide()Show()することで、それぞれのフォームオブジェクトは非表示になっている
だけで破棄はされていませんので、メモリをその分消費することにもなります。
画面の仕様上、実行される環境、また想定しうるHide()されるフォーム数のボリューム的に
この方法で問題ないか確認する必要があるかと思います。
なお、毎回各画面を初期化して開く感じであれば、Hide()ではなく、フォームの破棄でよいと思います。
前回の内容を保持して再表示する必要があればHide()が簡単ですが、上記を検討してみてください。
-
こんにちは、MicroVAX さん。
MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。
みなさんからのレスポンスはご確認いただけましたでしょうか。
投稿いただきましたみなさん、情報ありがとうございます。
参考になると思われる投稿に、勝手ながら私のほうで回答としてマークさせていただきました。
解決に役立った投稿や、参考になった情報など、有効な情報には回答としてマークすることをお願いしています。
今後、同じ問題でこのスレッドを参照される方にも、有効な情報がわかりやすくなるかと思いますので、よろしくお願いいたしますね。
他にも、この件で情報をお持ちの方は、是非投稿をお願いいたします。それでは。
マイクロソフト株式会社 フォーラム オペレーター 山本 春海- 回答としてマーク MicroVAX 2010年9月2日 10:01
すべての返信
-
もう少し詳細な仕様がわからないと何を推薦(紹介)して良いのかわかりませんが、書かれているメニューがアプリケーションのメインのメニューだとすれば、MDIという選択もあります。WindowsFormはその内部で動的に切り替えてWindowsFormを表示できませんので、MDIとして実装するか、複数のフォームを切り替えるしかないと思います。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/ -
> 質問3 質問1、質問2の以上に推奨できる実装方法があれば教えてください。
推奨までいきませんが、こういう方法もあるということで。
ちょっと変わった設計ですが、アプリケーションに Form を一つしか設けず、メニューや業務の流れに応じて、 表示するUserControl を切り替えるという案件がありました。
Form をコンテナとしか機能させず、業務処理を全て UserControl に任せてしまうというものです。その時はこんな方法もあるのかと感心したものですが、自分が設計するならこの手法は用いないかも。
ひらぽん http://d.hatena.ne.jp/hilapon/ -
私も MDI をイメージしました。ただ、MDI にしてしまうと幾つかの MDI らしい動作をしてしまうため、それらが気に入らない場合には、ひらぽんさんが書かれているような UserControl による実装が手軽だと思います。その場合は、よくインストーラー等で表示されるような、手順をおって画面が遷移していくタイプの雛型が、"Wizard" などで検索するとゴロゴロ出てくると思います。
他の方法として私が用いることがあるのは、ApplicationContext の派生クラスを作成することです。
通常の WinForms アプリケーションだと、Application.Run に対して ApplicationContext を与えないため、標準の ApplicationContext が使用されます。この ApplicationContext は「最初のフォームが閉じるとアプリケーションが終了する」というものですが、ApplicationContext を派生して動作をカスタマイズできます。
ここで「最初のフォームが閉じると、2番目のフォームを表示する。2番目のフォームが閉じると、閉じた条件にあわせて3番目のフォームが表示されたり、最初のフォームが表示される。3番目のフォームが閉じたらアプリケーションは終了する。」といったフォーム遷移のロジックを実装することができます。
フォーム切替のタイミングで Show/Hide の順序を調整すると、まるで中身が入れ替わったように見せることもできます。(エフェクトとか追加されてるとばればれですが...) -
メニュー選択が「menuStripコントロール」を指すならば、みなさんの仰っている通りMDIで実現可能です。
フォームに「menuStripコントロール」を配置し、フォームの「IsMDIContainer」プロパティをTrueにします。
http://dobon.net/vb/dotnet/form/mdiapplication.html
Hide()/Show()で切り替えとありますが、Hide()した後にShow()すれば、当然Hide()する前の画面の状態
で再表示される感じになりますので、もし画面の内容を初期化する必要がある場合は、そのコードを
実装する必要があるかと思います。
また、多くのフォームをHide()Show()することで、それぞれのフォームオブジェクトは非表示になっている
だけで破棄はされていませんので、メモリをその分消費することにもなります。
画面の仕様上、実行される環境、また想定しうるHide()されるフォーム数のボリューム的に
この方法で問題ないか確認する必要があるかと思います。
なお、毎回各画面を初期化して開く感じであれば、Hide()ではなく、フォームの破棄でよいと思います。
前回の内容を保持して再表示する必要があればHide()が簡単ですが、上記を検討してみてください。
-
こんにちは、MicroVAX さん。
MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。
みなさんからのレスポンスはご確認いただけましたでしょうか。
投稿いただきましたみなさん、情報ありがとうございます。
参考になると思われる投稿に、勝手ながら私のほうで回答としてマークさせていただきました。
解決に役立った投稿や、参考になった情報など、有効な情報には回答としてマークすることをお願いしています。
今後、同じ問題でこのスレッドを参照される方にも、有効な情報がわかりやすくなるかと思いますので、よろしくお願いいたしますね。
他にも、この件で情報をお持ちの方は、是非投稿をお願いいたします。それでは。
マイクロソフト株式会社 フォーラム オペレーター 山本 春海- 回答としてマーク MicroVAX 2010年9月2日 10:01