(VB2008)Form1からShowDialogしたFormを閉じた時の挙動について

このQ&Aのポイント
  • (VB2008)ShowDialogしたFormを閉じた時の、画面の挙動についてについて調査しました。特に、Form2をShowDialogしてからHideを実行すると、Form2が消えるが、残るForm1がデバッグ実行時は後ろに隠れ、リリースビルドではちらつく現象がある。これを回避する方法などについて教えてほしい。
  • 実験の結果、Me.Hide()の後にThreading.Thread.Sleep(5000)を記述すると、Form1が5秒間隠れてから表示されることがわかった。また、他のアプリによってはForm1が隠れるが、ExcelやIEでは隠れないようである。さらに、Closeメソッドを使用するとForm1は隠れないが、Sleepメソッドの間は表示されたままとなる。ShowDialogではなくShowメソッドを使用しOwnerを指定すると問題がないが、Ownerを指定しない場合はShowDialogと同じ挙動となる。
  • 以上の現象を調査しましたが、具体的な回避策や現象の原因については分かりません。この問題に関する詳しい説明がある場合、教えていただきたいです。
回答を見る
  • ベストアンサー

(VB2008)ShowDialogしたFormを閉じた時の、画面の挙

(VB2008)ShowDialogしたFormを閉じた時の、画面の挙動について (VB2008EE、OSはVista) Form1からForm2を(ボタンのクリックイベントで) Dim f As New Form2 f.Show(Me) と記述して表示させたあと、 Form2の(ボタンのクリックイベントで) Me.Hide() として、Form2を閉じる記述を書きました。 で、Form2をShowDialogしてから、Hideを実行すると、 Form2が消えるのはいいのですが、残るForm1が、 ・デバッグ実行時は、VB2008EEのWindowの後ろに隠れてしまい、そのままとなる。 ・リリースビルドでは、さすがにそのままとはなりませんが、一旦Form1が  ちらつきます。 この回避策がありましたら教えてください。 。。。 ここからは、いろいろ実験した結果です。 ・試しに、Me.Hide()の後ろに、Threading.Thread.Sleep(5000)を 記述して実行すると5秒間Form1が後ろのアプリ画面に隠れた後、 Form1が前に表示される。 ・この場合の「後ろの別アプリのWindow」について、その別アプリが VB2008やエクスプローラだとForm2がそのアプリに隠れるのですが、 ExcelやIEだと、Form1が後ろに隠れることがないようです。。。 ・Hideではなく、Closeだと、後ろには隠れません。 (ただし、Closeの場合、Threading.Thread.Sleep(5000)の間はForm2は その前にClose()があっても、表示されたままSleepしその後閉じます) ・さらにShowDialog()でなく、Show()の場合、Owner指定して実行した場合は、 (つまりSHow(Me))全く問題なく、Form1が前面に表示されたまま 他のアプリが前に来ることはないのですが、 Ownerを指定せずにShowしたところ、ShowDialogと同様のことが起きるようです。 もし、これらの現象全体についてしっかりと説明できる方がいらっしゃれば、 説明もしていただけるとうれしいです。

noname#166246
noname#166246

質問者が選んだベストアンサー

  • ベストアンサー
  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.6

閉じられちゃったけど、 http://www.mag2qa.com/qa6229196.html > 試しに、FormClosingイベントハンドラでHide()→e.cancel=Trueって > そうすると、アプリ(Form1)が閉じるボタンで終了しなくなって Owner に設定しているとなるみたいですね。。。^^; Public Class Form1   Private f As New Form2   Private Sub Button1_Click(省略) Handles Button1.Click     'f.Show()'←これだけなら終了できる     f.Show(Me)'←Button2を押せば終了できる   End Sub   Private Sub Button2_Click(省略) Handles Button2.Click     f.Owner = Nothing   End Sub End Class Public Class Form2   Private Sub Form2_FormClosing(省略) Handles Me.FormClosing     Debug.WriteLine("Form2_FormClosing")     e.Cancel = True     Me.Hide()   End Sub End Class 閉じようとする場合に、自分の持っているオブジェクトを破棄しようとしますから Form2 を所有している設定なので、破棄しようとするのかと。 Owner 指定しない場合は、Form1 は終了できますね。プロジェクトのプロパティで [シャットダウンモード]は[スタートアップフォームが閉じる時]が規定値ですので、 Form1 が閉じるのをキャンセルしていなければアプリも終了できます。 [最後のフォームが閉じる時]にしていれば当然閉じません。。。 > つまり、アプリの終了処理(メインフォームのFormClosing?)で > 非表示になっているフォームインスタンスにアクセスして > 必要なものをHDDに保存する、ということでは、まずいのでしょうか。 設計思想として、オブジェクト指向としては同じ目的のものはまとめて おきたいかな。保存する処理を実行するのが親フォームなら、保存する データを1箇所で管理したいです。保存する時に別クラスにアクセス しないと情報が揃わないというのがイマイチです。 あと、ここまでの手法を総合して、定石がどちらになるか?ということです。 ベースのプログラムの流れを変えずに、目的に応じた応用が利くほうがいい です。同じ手法を繰り返し使う方が、バグを少なくできます。 ここは性格や思想も影響するでしょうね。私は多少の手間で同じ手法に統一 できるなら、そちらを採用します。業務用アプリは数万行のコードを書くわけ ですし、20行くらい増えても保守性が高くなるなら手間ではありません。 >つまり、単純な検索BOXのように 確かにそれは非表示にして使いまわしてもいいでしょう。でも、他に破棄する ダイアログ表示があるなら、私は破棄で統一します。 逆も然り。わざわざシングルトンのサンプルを紹介したのも、画面に大量の コントロールが貼られて、インスタンスの生成自体が重いなどというアプリも 存在するからです。全ての画面を通じてインスタンスを使いまわす設計を 採用する場合もあります。が、頻度としては少ないです。また、一般論で説明 する場合、更に相手が初心者であることも多い場で、わざわざ問題の起こり やすい非表示を勧めたりはしないということです。 > 2010EEだと、問題は起きないと書きましたが、なぜか再度行ったら再現しました。 ちょっと VB 自体が不安定になってきてる感がありますね。 論理的に動きがおかしいと感じたら、リビルド。それでも駄目な場合は、 ビルドで作成されるファイルを物理的に削除してビルドしてみてください。 (既定でプロジェクトの下にできる bin と obj のフォルダをゴミ箱へ)

noname#166246
質問者

お礼

いやはや、閉じてしまった別質問への補足までしていただき、 本当にありがとうございます。 Close/Hideについての考え方についても、納得です。 しつこいくらいに聞いたかいがありました。 論理的なやり取りができて(変な言い方ですが)楽しかったです。 またよろしくお願い致します。 これでひとまず一区切りと思いますが、 私自身が訂正したくなるかもしれないので、 今週いっぱいくらいは、この質問は閉じないでおきます。

その他の回答 (5)

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.5

> 再表示時に検索した単語が再度表示される(コンボボックスとかから > 選べるようにする)のは良いけれども、やるのであれば、 > そのまま「非表示」にせずに、どこかに保存して、いったんFormを > Close&Disposeすべきということでしょうか。 そうですね。どうせやるならプログラムを終了した後も覚えておく 方がいいでしょう? 「ダイアログ初期表示の時に前回の入力項目を表示する」 という仕様であれば、そのためにコードを書きますので、フォーム を破棄せずに残しておく必要は無いです。 また、一般には、インスタンスは複数生成されるものですから、破棄 せずに残しておくなら、その管理方法を考えなければなりません。 複数画面を表示するプログラムでは、前回の入力といってもどれだか 分かりません。一般には未入力の状態で初期表示する事になるでしょう。 次の質問の回答でリンクを載せましたが、シングルトン設計で、完全に フォームクラスを1つのインスタンスで使いまわす設計の時は、場合に よっては利用するかもしれません。 ただ、ダイアログ表示の場合、その情報はダイアログを呼び出した親 フォームが管理しているデータを一部取り出したものが多いです。 この意味でも、ダイアログの初期表示で必要なデータは親から渡す 場合が多くなります。 例えば、ダイアログでキャンセルした場合、変更は反映されず、次回の 初期表示は親から渡す変更前のデータであるべきで、前の入力を残して おくプログラムでは意味がありません。 このように、前回の入力値を残す為に非表示のフォームを残す意味は ほとんどなく、むしろ、初心者がインスタンスを破棄せずに忘れたり、 初期表示のための処理(場合によっては変更前に戻す処理)の方が必要に なったりで、出番がないです。マイナス要素が大きいので使いません。

noname#166246
質問者

お礼

ありがとうございます。

noname#166246
質問者

補足

質問の本題から離れたところまでお付き合いいただいて、 本当にありがとうございます。 しつこい性格なのでもう少々お付き合い下さい。 > どうせやるならプログラムを終了した後も覚えておく方がいいでしょう? これは分かるのですが、これはプログラムの終了処理で 別途行ってもかまいないような気がいたします。 「HDDに保存」を毎回閉じたときに行うのではなく。 だとすれば、逆に言えば、毎回フォームを破棄する必要もないのではないでしょうか。 つまり、アプリの終了処理(メインフォームのFormClosing?)で 非表示になっているフォームインスタンスにアクセスして 必要なものをHDDに保存する、ということでは、まずいのでしょうか。 複数インスタンスは想定していませんので、以下、 シングルトンを前提にしたいと思います。 (別質問へのご回答もありがとうございました。) 場合分けして考えたいです。 つまり、単純な検索BOXのように、メインフォームから情報を渡す必要のないものと、 渡す必要があるものです。 後者については、おっしゃることはごもっともと思います。 私も前回の補足を書くときに、コードのどこかでいじられるか 保証できないような情報が必要なフォームだと、非表示では おかしなことになるなあと思っておりました。 で、残るは前者の場合です。 この場合は、破棄せずに非表示状態を使っていてもいいのではないか、というのが、 最後に残った疑問です。 Excel(2003)の検索Boxは、ComboBox(?(みたいなもの))のテキスト入力位置に テキストを入れたあと、その単語で検索せずに、そのまま閉じて再表示したとき、 ComboBoxのリストには追加されずに(検索実行前のため)、テキスト位置 に前回の入力がそのまま残っております。 いかにも、(モーダレスなので)Show→Hideをしたかのようです。 もちろんComboBoxのリストとは別に"Text"を保存しておけば再現可能なのですが、 そこまでして、破棄しなければならない理由もやはり分かりません。 やっても構わないし、破棄しなければならないという特別な理由もないけれども、 定石として行わないんだよ、という割り切りなら、それで構わないのですが。。。 。。。 なお、Showの場合でどーしてもHideを使いたいって場合、 閉じるボタンの対策が必要になってしまいます。 閉じるボタンではDisposeになりますので、ここで、内容を保存するような 処理をどーせ記述するのであれば、わざわざHideする意味はそれこそ本当に ないのではないかと思えてきます。 そういった理由もありますかね。 閉じるボタンでHide処理できないかと思ったのですが、、、 これは別質問で別途上げたいと思います。 こんなこと考えるくらいなら素直に毎回Disposeしたら? という気もしてきましたが。 。。。 ここからは、前回補足の訂正です。念のため。 (MARU4812さんへということではありません。 ついでにここに書かせてください) 2010EEだと、問題は起きないと書きましたが、なぜか再度行ったら再現しました。 昨日のプロジェクトは保存していなかったので別プロジェクトになってしまっていますが。 何度かShowDialog→Hideを行っていると、Form1が後ろに隠れることがあります。 もうShowDialog→Hideは行わない方針なので、気にすることもないのですが、一応。 本当は、問題の起きなかったVB2010EEで、.NetのFrameworkのバーションを変えて 試してみようと思ったのですが、、、やるまでもなく再現してしまいました。

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.4

> 最前面への移動は、なかば無理やりですが 環境依存というか、OS も影響してそうというだけで、 原因は追究できていないので、強制的なのも仕方なし ですね。新規でシンプルなプログラムでも再現するの ですよね? 色々なルールが重なって分かり難くなった部分と、 もともと仕様が統一されていない(過去の仕様を引き ずってたりする)部分があって、きれいに理解できない ことは多々ありまして^^; 結局、予備知識をもとにテストコードで実行結果を 検証しないと分からないんですよね。。。 私も VB に関しては色々なサイトから情報を仕入れ、 日々掲示板の投稿にも目を通してますが、未だに 知らなかった仕様に出会う日々です。。。 >A・Loadイベント >B・FormClosingイベント >C・FormClosedイベント >D・前回表示の際に設定~ そこは Disposed イベントも用意されていますので、 好きなだけ検証してみてください。 http://msdn.microsoft.com/ja-jp/library/system.componentmodel.component.disposed.aspx フォームに限らず、コンポーネントはコンストラクタで インスタンスを生成して Disposed イベントで破棄 されます。Disposed イベントが実行されていなければ 破棄されていないってことです。 > このDisposeはCloseの後だろうがなんだろうが破棄したい場合には > 別途必要と理解しました はい。ShowDialog ではそれでいいと思います。 > 前の文章 > ~ Close メソッドは .NET Framework によって > 呼び出されません。 FormClosed イベント起こってるんだからウソですよね。。。 Dispose が呼び出されないと読み替えて良いんじゃないかと。 > Hide以外の全ては、ABC全てのイベントが起きます。 結局、閉じる処理なんですよ。戻り値を代入するのも、閉じる 命令も。で、Hide だけは非表示の命令です。 ここは、Show の Hide を思い浮かべてもらった方が理解しやすいかも。 Close ・閉じるんだけど、呼び出し側で戻り値を利用する為に破棄しない。 Hide ・非表示にするだけなので破棄しない。 …なんですが、モーダルダイアログの次のコードが実行される 条件は http://msdn.microsoft.com/ja-jp/library/aa984358(v=VS.71).aspx 「終了する」と「非表示にする」の2つとも含むんですね。 以上を総合的に見た結果が、ご提示のテスト結果ではないかと。 > その後の再表示でLoadイベントが起きるのがちょっと? はい、たまに話題にあがります。 http://d.hatena.ne.jp/Kazzz/20070913/p4 > ShowDialogの後のHideの意味って、全くないような気がしてきました。 敢えて意味付けるなら、閉じないで非表示です。 …が、モーダル状態は解除されます。 > 仮に前回表示の入力を残しておきたいと思ったとしても、 職業プログラマはそういったコードを避けるでしょうが。 > CloseでもDialogResult設定でもいいわけですから。 DialogResult が変わればまだ可愛げがあるんですが、Cancel が返ってきました。 magicalpass さんも最初から言ってますが、Hide を使わない 方がいいのでは?

noname#166246
質問者

お礼

ありがとうございます。

noname#166246
質問者

補足

> 新規でシンプルなプログラムでも再現するのですよね? 再度ソリューションから作成しなおして実行しましたが ちゃんと?再現しました。 で、追加情報ですが、VB2010EEで試してみたところ、 まったく再現しませんでした。 安定してます。。。 環境依存ってことですね。 Hideのときにちらつく、という軽度の症状は、再度検索したら、ここでも 話題になっていたようですので、私だけではなさそうです。 http://bbs.wankuma.com/index.cgi?mode=al2&namber=39228&KLOG=67 。。。 > そこは Disposed イベントも用意されていますので、 なるほどーということで、早速検証しました。 完全に予想通りの結果になりました。 つまり、Show()→Close(または閉じるボタン)の場合のみ呼ばれ、 それ以外は呼ばれることはなかったです。 > FormClosed イベント起こってるんだからウソですよね。。。 なるほど~。 ウソとまで、言い切っていただくと、とーーーてもすっきりします。 >> 仮に前回表示の入力を残しておきたいと思ったとしても、 > 職業プログラマはそういったコードを避けるでしょうが。 ここ、ここのところ、その意図を詳しく教えてくださいませんか。 例えば、検索ダイアログでは、以前検索した語彙が出てくる方がよいと 思いますし、実際そうなっているものが多いと思います。 なので、なぜそのようにおっしゃっているのかがよく分かりません。 再表示時に検索した単語が再度表示される(コンボボックスとかから 選べるようにする)のは良いけれども、やるのであれば、 そのまま「非表示」にせずに、どこかに保存して、いったんFormを Close&Disposeすべきということでしょうか。 > Hide を使わない方がいいのでは? そうですね。なんか不安定だしわからない部分が多いので、 特にモーダルFormに対してはその方向にしたいと思います。 。。。 モーダレスに対してはまだ諦めてないんでけど、、、 こちらは、不明点を別途質問しました。 http://www.mag2qa.com/qa6228334.html です。 よろしければ、こちらもお願いいたします。 (もちろん他の方も)

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.3

VB2008 Professional Windows XP(SP3) で Form だけの単純プログラムでは再現しませんでした。 質問の本意ではないんだけど、ShowDialog したら Dispose してください。 ShowDialog は戻り値を受け取る事が前提なので破棄されません。 (プログラム終了時まで非表示で残り続け、New Form2 すると別の Form2 を 作成します。) http://msdn.microsoft.com/ja-jp/library/c7ykbedk > ダイアログ ボックスとして表示されているフォームは Close メソッドで > 閉じられることはないため、フォームがアプリケーションで不要になった > 場合は、そのフォームの Dispose メソッドを呼び出す必要があります。 Window の最前面への移動は OS 上では、SetForegroundWindow 関数(API)が 実行されていると思われますが、色々と条件があります。 http://msdn.microsoft.com/ja-jp/library/cc411039.aspx 最新の OS での情報は引っ掛からなかったので、参考程度に。

noname#166246
質問者

お礼

ありがとうございます。

noname#166246
質問者

補足

うー、環境依存ですか。困ったもんです。 。。。 最前面への移動は、なかば無理やりですが、Form1のRefresh()を Form1でのForm2のShowDialog実行後、または、Form2のHideメソッドのあとに、 入れる(Me.Owner.Refresh())ことで、一応前に戻ってくるようになりました。 (単なるFocus()ではダメでした、この辺も理解できてないです) 。。。 Disposeの件ありがとうございます。注意したいと思います。 引用していただいた部分の前の文章との関係がわかりにくかったので 調査してみました。 前の文章とは、 > モードレス フォームとは異なり、ユーザーがダイアログ ボックスの > 閉じるボタンをクリックするか、DialogResult プロパティの値を > 設定した場合には、Close メソッドは .NET Framework によって > 呼び出されません。その場合はフォームが非表示になるだけで、 > ダイアログ ボックスの新しいインスタンスを作成しなくても > そのフォームを再表示できます。 です。 で、その後、引用していただいた以下の部分へと(段落分けせず)続いています。 > ダイアログ ボックスとして表示されているフォームは Close メソッドで > 閉じられることはないため、フォームがアプリケーションで不要になった > 場合は、そのフォームの Dispose メソッドを呼び出す必要があります。 読んだだけですと、DialogResultの設定や、閉じるボタンでは、確かに 閉じられないけれども、Closeを意図的に呼んだ場合は、破棄されるようにも 読めます。 つまり、 「Close メソッドは .NET Framework によって呼び出されません。だから~」 だけど、Closeを呼んだ場合は違いますよ、と。 しかしながら、NO.2の補足にも書いたように、Closeであっても 破棄されないようですね。 (これがおっしゃりたかったことですよね?) このDisposeはCloseの後だろうがなんだろうが破棄したい場合には 別途必要と理解しました。 (MSDNの説明がわかりにくすぎ) 。。。 誤解してるよ、っていう場合は再度ご指摘をお願いいたします。 。。。 で、以下の5種類に違いがあるかを調べてみました。 ・DialogResultの設定(Formの同プロパティをコードで設定) ・DialogResultの設定(同プロパティ設定のButtonをクリック) ・閉じるボタン(フォームのxボタン) ・Close ・Hide 調べたのは、ShowDialogされるForm2の、 A・Loadイベント B・FormClosingイベント C・FormClosedイベント D・前回表示の際に設定したテキストボックスの文字が再表示時に残っているかどうか (再表示は同じForm2インスタンスでNewしてません) です。 結果はHide以外は全て同じで、Hid?eだけが違いました。 Hide以外の全ては、ABC全てのイベントが起きます。 (一旦閉じたあとの再表示でもLoadイベントも再度起きました) また、Dも残っていました。 Closeでも残ってます。その後の再表示でLoadイベントが起きるのがちょっと? HideではFormClosedイベントは起きませんでした。 Loadイベントは他と同じで、その後のShowDialogによる再表示でも起きました。 (この意外な?結果は既知でしたが) FormClosingイベントは、一回目の表示のあとなど (アプリ実行直後、または、Closeの後、など)では、起きるのですが、 再度ShowDialogしてHideするときには起きませんでした。。。 (MSDNに載っていないのかと、探したのですが見つかりませんでした。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.form.formclosing.aspx ) 。。。 ShowDialogの後のHideの意味って、全くないような気がしてきました。 なんかあるのでしょうかね。 仮に前回表示の入力を残しておきたいと思ったとしても、 CloseでもDialogResult設定でもいいわけですから。

回答No.2

#1 です。 ごめんなさい。HideでもShowDialogが終了するんですね。 HideとCloseの違いは再表示のためのFormのリソースを確保したままかどうかと思いますが。 Hide  非表示の処理を即実行  イベントハンドラの残りを実行  (Form1をアクティブにする) Close  イベントハンドラの残りを実行  Formリソースの解放(終了)  (Form1をアクティブにする) この違いじゃないかと。 試しにForm2noHideやCloseの後でForm3を表示させたら、こういう順番かと。 実際にイベントハンドラの処理が残ってなくても、なんらかでForm2の非表示やForm1がアクティブになるタイミングが微妙に違うのかもしれません。

noname#166246
質問者

お礼

ありがとうございます。

noname#166246
質問者

補足

それがですね。。。 Closeでもリソースを解放しないようです。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.form.close.aspx この解説の部分です。 「解説」の部分の、「次の2つの条件が満たされている場合」が ORなのかAND条件なのか分からず、実行して確かめました。 ShowDialog→Closeしたあとでも、そのままそのForm2の変数で(Newしなくても) 再度ShowDialogできるので、ORだと解釈しました。 つまり、(MDIうんぬん関係なく)「ShowDialog を使用してフォームを表示」した場合、closeをしても、「フォームが破棄されることはない」が正しいのではないでしょうか。 (これは、その後の文でも「これらの場合は」と複数の場合を想定していることからも わかります。) また、Form2に置いたTextBoxに文字を入力してからCloseして、再度ShowDialogしても その文字はちゃんと残ったままです。イメージとしてはHideと同じですねえ。 私もCloseは廃棄、Hideは表示を一時的に消すだけと思っていましたが違うようです。 他にもいろいろ実験しましたので、追加情報はNo.3の方の補足に書きたいと思います。

回答No.1

 Form2をHideしている理由は何ですか?  通常、Formを終了するときにわざわざHideする必要は無いと思いますが。(Closeの必要もありません)  Windowsフォームアプリケーションでは終了させるボタンのプロパティに終了コードが設定されていれば、そのボタンのイベントハンドラの実行後に自動的にFormが終了します。Hideする必要はありません。イベントハンドラでわざわざHideを行っているから、その分だけFormのやりくりの動作が掛かっているだけじゃないのでしょうか。  終了コードが設定されずにShowDialogしたままだとForm1には制御が戻らないので、制御が戻ってるなら正常にShowDialogが終了しています。Formを終了させるのならHideする意味がありません。  何か意味があってやっているのでなければ、余計な処理は入れない方が良いでしょう。  Hide……起動中のウインドウを一時的に隠すために使う    (ShowDialogで起動されてる場合は起動元のFormに制御は戻りません)  Close……プログラムの任意の場所からウインドウを終了させるために使う    (ボタンに終了コードが設定されている場合は自動的にCloseされる)

noname#166246
質問者

お礼

ありがとうございます。

関連するQ&A

  • (VB2008EEです)Form1からForm2をモーダレスで表示(S

    (VB2008EEです)Form1からForm2をモーダレスで表示(Show(Me))したのち、 Form2を、(Form2の)閉じるボタン(右上にあるXボタン)で閉じるときに、 単にHideするだけの処理に変更することは可能でしょうか。 デフォルトでは、閉じるボタンですと、Close()と同様、 Close(&Dispose)となると思いますが、Hide()処理に 変えられるかということです。 。。。 試しに、FormClosingイベントハンドラでHide()→e.cancel=Trueって やってみたところ、(再度同じForm2のインスタンスを使ってShowができ、 さらに前回のText表示などが残っているなど)その場はうまく行ったように 見えたのですが、そうすると、アプリ(Form1)が閉じるボタンで終了しなくなって しまいました。 (Application.Exitでもダメ、Endでは(強制終了とのことなので)OKですが) Form2のClose処理をCancelしているからだ、とは思いますが。 ShowDialog→Xボタン(同じ記述のまま) の後では、終了可能です。 では、Show→Xボタンのあとで、同じインスタンスで、上記と同じように、 ShowDialog→Xボタンとしたあと、Form1のXボタンでアプリを 終了させようとするとどうなるか。 結果は、終了不能でした。 一度Show→Xしたらそれをどこかに覚えている?ってことなのでしょうか。。。 ここらへんの現象まで、合わせて説明できる方がいらっしゃったら 合わせてご説明いただけませんでしょうか。 。。。 なお、なぜこんなことするの?という実際論はここではなしで 純粋に技術論でお願いいたします。

  • VBでの質問です

    VBでの質問です Form1と2があるとします Form1とあるボタンを押すとForm2が開きFormが閉じるようにしたいのですがうまくいきません。どうしてでしょうか? Form1のコードで Form2.show Me.Close() と記述しましたがどこが違うのでしょうか。

  • form2 から form1に戻ったとき、form1のTextboxの内容を消したくないのですが

    .NETのBasicでform1からform2に移行するため Dim F2 As New Form2() Me.Hide() F2.Show() この後、form1にもどるため Dim F1 As New Form1() F1.Show() Me.Hide() 上記のように書くと、form1のTextboxの内容が消えてしまいますよね。 これを消さずにまたform1のTextboxの編集が続けられるようにしたいのですが、どうすればいいでしょうか ただ単にform1を見えなくする方法が違うのでしょうか 初歩的な質問ですいません。

  • showdialogを使わずにモーダル表示したい。

    VB2005環境です。 FormAから、FormBをShowしています。 FormB画面がある時は、FormAを触らせたくないので、 モーダル表示にしたいと考えているのですが、元々Showして 作っており、更にFormAがFormBのCloseイベントをハンドルして いろいろ処理を書いたせいか、原因が特定できないのですが、 ShowDialogしてcloseすると ystem.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。 とのエラーが出ます。 ShowでFormBを起動する作りのまま、FormAだけ触れないように したいのですが、Showでモーダル表示にできるような方法が ありましたら教えていただけないでしょうか? 宜しくお願いします。

  • VB2010の、Formを開く動作に関する質問です

    VB2010のFormについてお聞きしたいことがあります。 例えばForm1とForm2の2つがあるとして、 ・Form1上のボタンをクリック後Form2が表示される ・Form2を表示後Form1は自動で閉じられる。 この様な事をするにはどの様に行えばよろしいでしょうか? 試しに、 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click   Form2.Show()   Me.Close() End Sub と、してみたのですが Form2が表示された直後に1と2両方消えてしまいました。 改善方法を教えていただけると嬉しいです。 よろしくお願いいたします。

  • Form1からShow()で表示したForm2が、CloseまたはHi

    Form1からShow()で表示したForm2が、CloseまたはHideで消えたあと、 制御が戻ってきたForm1の側で、CloseされたのかHideされたのかを 判別する手段はございますでしょうか? あればその手段を教えてください。 無理なら無理でしょうとご指摘ください。 Form2の参照変数( Dim f As Form2 の f )はCloseでも Nothingにならないので「Is Nothing」では判別できませんでした。 参照はしているけど、その参照先が破棄(解放)されているって ことですよね。 他の変数を理由するという答え以外でお願いいたします。

  • Hideについて(.NET)

    Form1をHideで非表示にし、Form2を開いた後、再びForm1を表示したいのですがうまくいきません。 [form1のイベント] Dim frmForm2 as New Form2 frmForm2.Show Me.hide Sub End [form2のイベント] Dim frmForm1 as New Form1 frmForm1.Show Me.Close Sub End としてあります。 非表示されたフォームを再表示されずに、新しくフォームが開いてしまっていると考えられるんですが、どうしたらよいでしょうか? 

  • 続・タイマーとShowdialog(VB2010)

    タイマーコントロールについて の続きになります。 一つ方法を考えました。いくつか問題ありですが・・。 ApplicationEvent.vbの部分を Namespace My Partial Friend Class MyApplication Protected Overrides Function OnInitialize( _ ByVal commandLineArgs As _ System.Collections.ObjectModel.ReadOnlyCollection(Of String) _ ) As Boolean 'スプラッシュウィンドウを表示する最短時間を0.5秒にする Me.MinimumSplashScreenDisplayTime = 500 Return MyBase.OnInitialize(commandLineArgs) End Function      'スプラッシュスクリーンのタイマーコントロール設定 Friend Sub Splash() With SplashScreen1.Timer1 .Enabled = True .Interval = 500 End With SplashScreen1.Timer1.Start() End Sub ' この書き方あってますか?とりあえずは反映されてるようですけれど・・・ End Class End Namespace SplashScreen1の部分を Public Class SplashScreen1 Friend Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click     ' クリックで閉じる DialogResult = DialogResult.OK Me.Close() End Sub Friend Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick ' タイマーコントロール発動時、瞬時に停止させる。スクリーンは消えないように。 Me.Timer1.Enabled = False Me.ShowDialog() End Sub End Class と、してみましたが・・・問題が発生するのです。 この時、スクリーンフォームがMe.ShowDialog()と書いてあるにもかかわらず、 メインフォームとともに操作可能・・つまりモードレスであるShowで表示されるのです。上記のコードを実行してもらえれば分かると思いますが・・。 また、メインフォームが前方に、スクリーンフォームが後方に行ってしまいます。これはどのようにすれば良いでしょうか? Me.TopMost = True としても駄目でした。 BringToFrontを使っても同じでした。

  • VB.NET Form1からForm2を開いたり閉じたりする方法

    VB.NET2005でForm1にあるCheckBoxをTrueにするとform2をモードレスフォームとして開き、CheckBoxをFalseにするとform2を閉じる方法がわかりません。また、form2の[×]で閉じた時にはForm1にあるCheckBoxをFalseにする方法がわかりません。 '----------------------------------- Private Sub CheckBox2_CheckedChanged ・・・   Dim f_cnt As Integer   Dim form2 As New Form2()   f_cnt = My.Application.OpenForms.Count   If CheckBox1.Checked = True Then     If f_cnt = 1 Then form1.Show() 'モードレスフォームとして表示する   Else    form2.Close() ←閉じない   End If End Sub '-----------------------------------

  • Form1.vbをイベントなしで動作させるには?

    VB2005初心者で困っています。 Menu.vbとForm1.vb, Form2vb, Form3.vb・・・を作り、Menu.vbのButton1_ClickでForm1.Show()としてForm1.vbに移行し、次にForm1のButton1_clickイベントでExcelからDataを読み込んでGraphを書かせています。(この時は問題なく動作しています) これを、Form1に移行したらすぐにGraphを表示しようとして、Form1.vbの Public Class Form1 Private Sub Button_Clic(Byval sender As System・・・・・)Handles Button1.click   Dim g As Graphics   ・・・・ を変更して、  Private Sub Form1_Load(Byval sender As System・・・・)Handles MyBase.load Me.Show() Dim g As Graphics   ・・・・ と、しましたが、一瞬Graphは表示しますが、すぐに消えます。 また、罫線はまったく表示しません。 Button_ClickイベントなしでForm1を動かすにはどうすればよいのでしょうか?

専門家に質問してみよう