tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル 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 等が、
余計に問題を複雑化させているようにみうけられます。
原因を特定しないまま対処療法を続けるのは、あまり得策では無いと思いますよ。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。