タイトル : Re^7: 画面遷移 投稿日 : 2015/08/21(Fri) 10:44 投稿者 : 魔界の仮面弁士
> (ShowDialogはBやCのパターン行い、Usingは使用していません) Using を使うかどうかは任意ですが、その場合は「Dispose」が必要です。 Show の場合、フォームが閉じられたときに、自動的に Dispose されるため不要ですが、 ShowDialog した場合は、Close してもインスタンスは破棄されません。非表示になるだけです。 hhttps://msdn.microsoft.com/ja-jp/library/c7ykbedk.aspx 》 ダイアログ ボックスとして表示されているフォームは閉じられるのではなく非表示になるため、 》 フォームがアプリケーションで不要になった場合は、そのフォームの Dispose メソッドを 》 呼び出す必要があります。 各フォームの連携部分で、上記の違いは認識されていますでしょうか? > 現在は、現象が少ないAのパターンを採用しています。 > 過去に Cのパターン、Bのパターン、及びForm2.ShowDialog等を行いました。 暗黙のフォームを使った場合、インスタンスの管理が曖昧になるため、 閉じたフォームが再生成されて開かれたのか、 非表示だったフォームが再表示されたのか、分かり難くなります。 そのためコーディングミスにより、以前とは違うインスタンスを操作することで 意図せぬ画面遷移が行われてしまっているケースを見かけます。 たとえば、これは極端な例ですが ・モードレスなサブ画面を表示中は、呼びだし元のメイン画面を消す ・サブ画面が閉じたら、呼びだし元の画面を再表示する という処理を実装するにあたり、下記のような処理になっていることがありました。 'アプリケーション設定:シャットダウンモード=「最後のフォームが閉じるとき」 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Form2.Show() Me.Hide() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Form2.Show() Me.Close() End Sub End Class Public Class Form2 Private Sub Form2_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing Form1.Show() End Sub End Class この場合、Button1 と Button2 は明らかに違う意味を持つのですが、 各フォームの表示位置やサイズが固定化されていたため(というか最大化)、 実行時テストでは、両者のその違いに気付かなかったのだそうです。 (上記の場合、Hide と Close の違いが争点ではありますが、それとは別に Form2 内から、Form1 という暗黙インスタンスを操作していることも問題です) > ⇒InitialImage ⇒ ローカルリリースを選択してインポートしています(JPG) Local Release …というのは、 Local Resource のことでしょうか。 > ・500から6000個くらいのラベルを作成します その数になると、Label で処理するよりも、Paint イベントあたりで 描画処理として片付けた方が、処理が軽くなるのではないでしょうか。 まぁ、実装の手間としては Label の方が楽なのかもしれませんけど。 > > D は C の子画面なのでしょうか? > ⇒回答 > Form2.Showで開いている画面です。 Form2.Show したことと、それが子画面であるかどうかは無関係です。 Public Class Form2 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Form3.Show() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Form3.Owner = Me Form3.Show() End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Form3.Show(Me) End Sub End Class Button1 から呼び出した Form3 は、Form2 の子画面ではありませんが、 Button2 および 3 での Form3 は、Form2 の子画面です。動作の違いを確認してみてください。 ・親画面が閉じられると、子画面も一緒に閉じられます。 ・子画面は、常に親画面よりも手前に表示されます。 ※ 身近な「子画面」の例としては、「メモ帳」における「検索」画面などがあります。 ただ、Button3 のパターンは過去に試していて、その場合は 『頻繁に現象が発生しました。』とのことでしたよね。それは、 Form2 が、Form3 よりも手前に来てしまう状態であったという意味でしょうか? >> ・処理に長い時間(たとえば1秒以上)を要するイベントがありませんか? > ・はい 長い処理を UIスレッドで行うと、ウィンドウメッセージの流れを阻害してしまいます。 それらの処理を非同期処理として、ワーカースレッドで処理することを検討してみて下さい。 >> ・BringToFront/SendToBack/Activate などを意図的に呼び出しているイベントはありませんか? > ・はい(ShownでActivateを使用しています。) Activate は、(自アプリ内における)アクティブフォームの切替を行うための物ですよね。 複数の画面が立ち上がっていて、特定のフォームを明示的にアクティブにしたいときに使うことはありますが、 Shown 時に呼び出すべきようなものではありません。使いどころを見直してみてください。 > > ・暗黙のフォームインスタンスを利用していませんか? > > ⇒回答 > > ・はい > > ⇒明示的インスタンスを利用して動かすと頻繁に問題が発生します。 同じフォームを複数開くことがないのであれば、暗黙でも明示的でも構いませんが、 この場合の争点は、フォームの有効期間をきちんと把握しているか否かです。 きちんと管理されているなら、暗黙だろうと明示的だろうと、同じ動作になるはずですし、 暗黙か明示的かで動作に影響があるのなら、フォームの取り扱い方に問題があることになります。 > クリックしてから画面が表示される間です Shown で Activate するなど、あまり一般的では無いフォーカス制御を行っているようですし、 話を聞く限りでは、問題を解消しようとするために仕掛けた TopMost や Activate 等が、 余計に問題を複雑化させているようにみうけられます。 原因を特定しないまま対処療法を続けるのは、あまり得策では無いと思いますよ。 |