モーダル制御について
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/11/10 16:59:24
複数のフォームを触れるようにしたいのであれば、
そもそもモーダルを選択すべきでは無いと思いますよ。
たとえば Form3 もモードレスに切り替えて、
「Form3 の表示中は Form1 を Enabled = False にしておく」では駄目でしょうか。
> 「form3」を出している状態で「form2」だけは触れるようにしたいです。
どうしても Form3 をモーダルにしておきたいのであれば、
Form3 を表示する前に Form2 を Hide() しておき、
モーダル表示した Form3 の Shown イベントで Form2 を表示しなおすという手があります。
ただしこの方法は、フォーム間の依存関係が複雑になるのでお奨めしません。
(Form3 を閉じる前には、Form2 の Owner を Form3 から Form1 に戻す処理も必要)
そもそもモーダルを選択すべきでは無いと思いますよ。
たとえば Form3 もモードレスに切り替えて、
「Form3 の表示中は Form1 を Enabled = False にしておく」では駄目でしょうか。
> 「form3」を出している状態で「form2」だけは触れるようにしたいです。
どうしても Form3 をモーダルにしておきたいのであれば、
Form3 を表示する前に Form2 を Hide() しておき、
モーダル表示した Form3 の Shown イベントで Form2 を表示しなおすという手があります。
ただしこの方法は、フォーム間の依存関係が複雑になるのでお奨めしません。
(Form3 を閉じる前には、Form2 の Owner を Form3 から Form1 に戻す処理も必要)
投稿者 さしみマン  (社会人)
投稿日時
2021/11/10 17:33:28
ご返信ありがとうございます。
>複数のフォームを触れるようにしたいのであれば、そもそもモーダルを選択すべきでは無いと思いますよ。
おっしゃる通りだと思います。
私の説明の仕方が悪かったのですが、元々「form1」にはモーダルのみでした。
ただ、モーダルを実装した後に、「モーダルが出ていても触れるフォーム」を作成することになりました。
----フォーム「form1」のコード---- ↓わかりづらくてすいません。モーダルが先です。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.ShowDialog()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
ですので、モーダルをモーダレスのものに変更することは出来ないです。
>複数のフォームを触れるようにしたいのであれば、そもそもモーダルを選択すべきでは無いと思いますよ。
おっしゃる通りだと思います。
私の説明の仕方が悪かったのですが、元々「form1」にはモーダルのみでした。
ただ、モーダルを実装した後に、「モーダルが出ていても触れるフォーム」を作成することになりました。
----フォーム「form1」のコード---- ↓わかりづらくてすいません。モーダルが先です。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.ShowDialog()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
ですので、モーダルをモーダレスのものに変更することは出来ないです。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/11/10 18:05:01
> 元々「form1」にはモーダルのみでした。
済みません。『Form1 にはモーダルのみ』という日本語の意味が分かりません。
元々 Form2 や Form3 はなく、Form1 のみをモーダルで表示していた、という意味でしょうか?
Form1 をスタートアップフォームとしていた場合、通常は、
暗黙の Application.Run メソッドによって起動されますが、
それを意図的に、Sub Main() から ShowDialog で呼び出していたとか。
それとも、ここでいう Form1 とは、フォーム名ではなくプロジェクト名なのでしょうか?
(Form1.exe が扱うフォームがすべてモーダルだった、という意味で)
なお、ShowDialog で呼び出したフォームは、Close メソッドを呼び出したり
右上の × を押したとしても、非表示になるだけでメモリ上には残ったままになります。
そのため Show メソッドで呼んだ場合とは異なり、呼び出し元が責任をもって
モーダルフォームを Dispose すう必要があることも忘れずに…。
https://dobon.net/vb/bbs/log3-42/25503.html
> モーダルをモーダレスのものに変更することは出来ないです。
モーダレスではなく、モードレスですね。
アプリケーションの仕様を変更することは出来ないと言っても、
Windows の動作仕様を変更することはもっと出来ないことなので、
正攻法としては、やはり下記のいずれかになろうかと思います。
案1) アプリケーションをモードレスに修正する
案2) モードレスを一時的に Hide して、モーダルの Shown イベントで表示しなおす
モーダルフォーム上から、モードレスフォームを表示することは可能ですが、
モーダルからモードレスに切り替えることはできないので、そのフォームは
Close なり Hide なり Visible = False なりで一度閉じてから開きなおす必要があります。
これが案2の手法にあたります。
ただし、そのフォームを Owner とする子フォームがいた場合、親が閉じられた(非表示も含む)時に
子フォームも連鎖して閉じられることになる点を考慮する必要があります。
案2 だと、フォーム間の依存関係が強くなり、手間も増えるので、
個人的には 案1 への移行を検討することをお奨めしておきます。
済みません。『Form1 にはモーダルのみ』という日本語の意味が分かりません。
元々 Form2 や Form3 はなく、Form1 のみをモーダルで表示していた、という意味でしょうか?
Form1 をスタートアップフォームとしていた場合、通常は、
暗黙の Application.Run メソッドによって起動されますが、
それを意図的に、Sub Main() から ShowDialog で呼び出していたとか。
それとも、ここでいう Form1 とは、フォーム名ではなくプロジェクト名なのでしょうか?
(Form1.exe が扱うフォームがすべてモーダルだった、という意味で)
なお、ShowDialog で呼び出したフォームは、Close メソッドを呼び出したり
右上の × を押したとしても、非表示になるだけでメモリ上には残ったままになります。
そのため Show メソッドで呼んだ場合とは異なり、呼び出し元が責任をもって
モーダルフォームを Dispose すう必要があることも忘れずに…。
https://dobon.net/vb/bbs/log3-42/25503.html
> モーダルをモーダレスのものに変更することは出来ないです。
モーダレスではなく、モードレスですね。
アプリケーションの仕様を変更することは出来ないと言っても、
Windows の動作仕様を変更することはもっと出来ないことなので、
正攻法としては、やはり下記のいずれかになろうかと思います。
案1) アプリケーションをモードレスに修正する
案2) モードレスを一時的に Hide して、モーダルの Shown イベントで表示しなおす
モーダルフォーム上から、モードレスフォームを表示することは可能ですが、
モーダルからモードレスに切り替えることはできないので、そのフォームは
Close なり Hide なり Visible = False なりで一度閉じてから開きなおす必要があります。
これが案2の手法にあたります。
ただし、そのフォームを Owner とする子フォームがいた場合、親が閉じられた(非表示も含む)時に
子フォームも連鎖して閉じられることになる点を考慮する必要があります。
案2 だと、フォーム間の依存関係が強くなり、手間も増えるので、
個人的には 案1 への移行を検討することをお奨めしておきます。
「form1」「form2」「form3」があるとして、「form1」に「form2」「form3」が開けるボタンを用意します。
----フォーム「form1」のコード----
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.Show()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.ShowDialog()
End Sub
このようなコードを書くと当たり前ですが、「form3」を出すと他のフォームは触れなくなります。
ただ、「form3」を出している状態で「form2」だけは触れるようにしたいです。
何か良い方法はございませんでしょうか?