DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Formの閉じられかたについて

環境/言語:[WinXP, VB.NET2008]
分類:[.NET]

開発経験が浅く、いつも本サイトを参考にさせていただいております。

Windowsアプリケーションを作成している段階で、疑問に思ったことがございまして、質問させていただきたく思いました。

3通りあるフォームの閉じられかたについて何か違いがあるのか?という質問です。

FormはFromAとFormBがあり、FromAを閉じるタイミングが違うようになっています。

1.
FormA
Private Sub Button1.Click
FormB.show
Me.close()
End Sub

2.
FormA
Private Sub Button1.Click
Me.close()
FormB.show
End Sub

3.
FormA
Private Sub Button1.Click
FormB.show
End Sub

FormB
Private Sub FormA_Load
FormA.Close()
End Sub

見た目の動作は同じように見えますが、コードの動きを追っても、あまり大差ないように思えました。
(どの処理も呼び出し元でFormAをshowし、呼び出し先のLoadイベントが終わったらまた呼出元の処理に戻り、Clickイベントが終わったらFromBに戻る)

基本的な事かもしれませんが、教えてください。
よろしくお願いします。
■No22532に返信(ぐんださんの記事)
> FormはFromAとFormBがあり、FromAを閉じるタイミングが違うようになっています。
FromA だと、求人情報誌になってしまう、というネタ突っ込みや、
提示されたサンプルの細かい文法エラーなどはさておいて…。


> 1.
> 2.
たとえば、シャットダウンモードが「最後のフォームが閉じるとき」に
なっていて、現在、FormA のみがロードされている状況だった場合には、
前者は、アプリケーションが終了してしまう可能性がありますが、
後者だと、アプリケーションは起動したままとなります。

> 3.
これは、先の 2 つとは微妙に意味が異なります。
<1>および<2>で使われる「Me」と、<3>の「FormA」は、
異なるインスタンスとなる可能性がありえるからです。

もし、同じインスタンスだった場合、先の<2> に近い動作となりますが、
Debug.Print を各イベントに配置して確認したところ、
以下のようなタイミングで、処理が流れていくようです。


<2>
 1) FormA.Button1_Click の開始
 2) →FormB.Show()
 3) FormB_Load の開始
 4) FormB_Load の終了
 5) →Me.Close() 'Send WM_CLOSE Message
 6) FormA_FormClosing の開始
 7) FormA_FormClosing の終了
 8) FormA_FormClosed の開始
 9) FormA_FormClosed の終了
 10)FormA.Button1_Click の終了

<3>
 1) FormA.Button1_Click の開始
 2) →FormB.Show()
 3) FormB_Load の開始
 4) →FormA.Close() 'Send WM_CLOSE Message
 5) FormA_FormClosing の開始
 6) FormA_FormClosing の終了
 7) FormA_FormClosed の開始
 8) FormA_FormClosed の終了
 9) FormB_Load の終了
 10)FormA.Button1_Click の終了
魔界の仮面弁士さん

ご回答ありがとうございます。

<2>と<3>が同じインスタンスだった場合〜についてもう少し教えてください。


ClosingとClosedのタイミングが違う事以外に、考えられる影響はあるのでしょうか?と言いますのは、自身のFormは自身で閉じるもの、というのが正しいのかそうでないのかがよくわかっておりません。。

書籍等で見ると、自身でClose()しているものがほとんどでしたので実際どうなのかなと思いました。



■No22537に返信(魔界の仮面弁士さんの記事)
> ■No22532に返信(ぐんださんの記事)
>>FormはFromAとFormBがあり、FromAを閉じるタイミングが違うようになっています。
> FromA だと、求人情報誌になってしまう、というネタ突っ込みや、
> 提示されたサンプルの細かい文法エラーなどはさておいて…。
>
>
>>1.
>>2.
> たとえば、シャットダウンモードが「最後のフォームが閉じるとき」に
> なっていて、現在、FormA のみがロードされている状況だった場合には、
> 前者は、アプリケーションが終了してしまう可能性がありますが、
> 後者だと、アプリケーションは起動したままとなります。
>
>>3.
> これは、先の 2 つとは微妙に意味が異なります。
> <1>および<2>で使われる「Me」と、<3>の「FormA」は、
> 異なるインスタンスとなる可能性がありえるからです。
>
> もし、同じインスタンスだった場合、先の<2> に近い動作となりますが、
> Debug.Print を各イベントに配置して確認したところ、
> 以下のようなタイミングで、処理が流れていくようです。
>
>
> <2>
>  1) FormA.Button1_Click の開始
>  2) →FormB.Show()
>  3) FormB_Load の開始
>  4) FormB_Load の終了
>  5) →Me.Close() 'Send WM_CLOSE Message
>  6) FormA_FormClosing の開始
>  7) FormA_FormClosing の終了
>  8) FormA_FormClosed の開始
>  9) FormA_FormClosed の終了
>  10)FormA.Button1_Click の終了
>
> <3>
>  1) FormA.Button1_Click の開始
>  2) →FormB.Show()
>  3) FormB_Load の開始
>  4) →FormA.Close() 'Send WM_CLOSE Message
>  5) FormA_FormClosing の開始
>  6) FormA_FormClosing の終了
>  7) FormA_FormClosed の開始
>  8) FormA_FormClosed の終了
>  9) FormB_Load の終了
>  10)FormA.Button1_Click の終了
2008/08/01(Fri) 20:04:07 編集(投稿者)

■No22540に返信(ぐんださんの記事)
> ClosingとClosedのタイミングが違う事以外に、考えられる影響はあるのでしょうか?

そうですね…。たとえば先の<3> 案の実装の場合、もしも
 「Button2 では、FormA を一時的に非表示にしたまま、FormB を表示させる」
といった追加仕様が発生した場合に、処理が冗長的になってしまいますが、
<2> 案であれば、そのような処理にも対処しやすい、などでしょうか。



> 自身のFormは自身で閉じるもの、というのが正しいのかそうでないのかがよくわかっておりません。。

そのアプリケーションの仕様次第なので、ある意味、どちらも正しいでしょう。
多くの場合、自身が閉じることになるとは思いますけれどね(私見ですけれども)。


たとえば MessageBox や OpenFileDialog の場合、[OK] 等を押すことで
その画面が閉じられますが、その閉じるための処理は呼び出し側には書かせず、
呼び出されたフォーム自身によって閉じるように実装されていますよね。

一方、モーダルフォーム(ShowDialog の場合)ではなく、モードレスフォームの
場合には、自身が閉じる場合もあれば、呼び出した側で閉じられる事もありますので
この場合、閉じる処理をどこに書くべきかは、アプリの仕様次第であるとも言えます。


たとえば、MDI 親フォームのメニューや、ツールバー上のトグルボタンなどに、
「子画面の表示/非表示を切り替える」という機能を用意するような場面では
親画面側に、子画面を閉じる(あるいは非表示にする)記述が書かれるでしょう。

しかし、その場合でも、子画面自体に設けられた [OK]/[Cancel]ボタンなどでは、
子画面を閉じる処理は、その子画面自身に記述されるのが妥当ですよね。
魔界の仮面弁士さん
確認が遅くなってしまい申し訳ありません。

ご丁寧なご回答ありがとうございます。
仕様によって動作が異なるのは至極当然だと思います。
その仕様を基に動作が適切かどうか、という点に注意すれば大丈夫ではないかと解釈しました。

色々とご助言ありがとうございました。
また何かありましたらその節はよろしくお願い致します。


■No22544に返信(魔界の仮面弁士さんの記事)
> 2008/08/01(Fri) 20:04:07 編集(投稿者)
>
> ■No22540に返信(ぐんださんの記事)
>>ClosingとClosedのタイミングが違う事以外に、考えられる影響はあるのでしょうか?
>
> そうですね…。たとえば先の<3> 案の実装の場合、もしも
>  「Button2 では、FormA を一時的に非表示にしたまま、FormB を表示させる」
> といった追加仕様が発生した場合に、処理が冗長的になってしまいますが、
> <2> 案であれば、そのような処理にも対処しやすい、などでしょうか。
>
>
>
>>自身のFormは自身で閉じるもの、というのが正しいのかそうでないのかがよくわかっておりません。。
>
> そのアプリケーションの仕様次第なので、ある意味、どちらも正しいでしょう。
> 多くの場合、自身が閉じることになるとは思いますけれどね(私見ですけれども)。
>
>
> たとえば MessageBox や OpenFileDialog の場合、[OK] 等を押すことで
> その画面が閉じられますが、その閉じるための処理は呼び出し側には書かせず、
> 呼び出されたフォーム自身によって閉じるように実装されていますよね。
>
> 一方、モーダルフォーム(ShowDialog の場合)ではなく、モードレスフォームの
> 場合には、自身が閉じる場合もあれば、呼び出した側で閉じられる事もありますので
> この場合、閉じる処理をどこに書くべきかは、アプリの仕様次第であるとも言えます。
>
>
> たとえば、MDI 親フォームのメニューや、ツールバー上のトグルボタンなどに、
> 「子画面の表示/非表示を切り替える」という機能を用意するような場面では
> 親画面側に、子画面を閉じる(あるいは非表示にする)記述が書かれるでしょう。
>
> しかし、その場合でも、子画面自体に設けられた [OK]/[Cancel]ボタンなどでは、
> 子画面を閉じる処理は、その子画面自身に記述されるのが妥当ですよね。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板