- PR -

画面遷移時に表示順が変わるのを防ぎたい

投稿者投稿内容
ジブ
大ベテラン
会議室デビュー日: 2005/09/22
投稿数: 135
投稿日時: 2005-11-24 22:36
B画面がCloseして自分自身のリソースを開放してもC画面からのイベントは受け付けている状況でないかなと推測します。

B画面が閉じられたときC画面へAddhandlerしたイベントハンドラをリムーブするか
自分自身がCloseされていたらShowしないようにすればよいのではないでしょうか?
さくら
ベテラン
会議室デビュー日: 2004/02/12
投稿数: 76
投稿日時: 2005-11-24 23:18
引用:

B画面がCloseして自分自身のリソースを開放してもC画面からのイベントは受け付けている状況でないかなと推測します。



B画面をCloseするときには、既にC画面はCloseされているはずなので
(C画面をCloseしないことにはB画面は表示されず隠れたままなので)
C画面からのイベントを受け付けている状況にはないのではないかと
考えるのですが、ジブ様が言われていることは
「消したと思っているはずのC画面のインスタンスが
 実は残っている(B画面が掴んでいる)のでは?」
ということで解釈あっておりますでしょうか…?

引用:

B画面が閉じられたときC画面へAddhandlerしたイベントハンドラをリムーブするか
自分自身がCloseされていたらShowしないようにすればよいのではないでしょうか?



B画面が閉じられたとき(=B画面上で「A画面へ戻る」ボタンが
クリックされたとき)、C画面へAddhandlerしたイベントハンドラをリムーブ
するようにしようとすると、今の状態では、
C画面のインスタンスを生成する際に
B画面上の「C画面を開く」ボタンのクリックイベント内で
C画面オブジェクトのスコープをローカル変数(Dim)で生成しているため、
B画面が閉じられたとき(=B画面上で「A画面へ戻る」ボタンがクリックされたとき)
のイベント内ではRemoveHandlerできないです…。
C画面オブジェクトのスコープをローカル変数としているところから
既に間違っているのでしょうか…。

私の解釈が誤っている点などありましたら教えてください。
どんなことでも結構ですので、こうじゃないかなと思うことなどあれば
ぜひまたお返事ください。
どうぞよろしくお願いします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-25 08:55
引用:

Jittaさんの書き込み (2005-11-19 06:38) より:

Form って、IDisposable … MustDispose なんですけど、Close って、Dispose と同等でしたっけ?ShowModal があるので、なんか、ややこしかったような?


Show で表示された場合は、表示された側のフォームで Close すれば Dispose も呼び出されます。
ShowDialog で表示された場合は、表示された側のフォームで Close し、呼び出し側で Dispose する必要があります。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-11-25 19:17
 プログラムは、作られたとおりにしか動けません。悲しいけれど、作ったとおりに動きます。
 なので、例外が発生するということは、例外を生成してしまうような作り方になっている、ということです。
 まずは、『既にC画面はCloseされているはず』のような、「こう動くはず」という思いこみを捨てるところから始めましょう。

 で、まず、調査です。ObjectDisposedException ということですから、生成−破棄のタイミングがずれていると考えられます。

各フォームのコンストラクタで、Form.Text に現在日時を書き込むなど、作られたオブジェクトを人間が識別できるようにします。
主要なメソッド、Click, Closnig, コンストラクタあたりかな?に、ログ出力をするコードを追加します。

これで、どの様な順序でメソッドが実行されるか、わかるようになります。
また、例外発生時に、そのオブジェクトがいつ破棄されるべきのものなのか、判別できるようになるでしょう。

 生成−参照−破棄の順番が明らかになったら、それが意図していない順番になっていないか、確認します。修正方法は、その順番が明らかになってからですね。
___________________________________________________________________
□ written by Jitta on 2005/11/25
□ Microsoft MVP for Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________
ジブ
大ベテラン
会議室デビュー日: 2005/09/22
投稿数: 135
投稿日時: 2005-11-25 20:52
引用:

さくらさんの書き込み (2005-11-24 23:18) より:

B画面をCloseするときには、既にC画面はCloseされているはずなので
(C画面をCloseしないことにはB画面は表示されず隠れたままなので)
C画面からのイベントを受け付けている状況にはないのではないかと
考えるのですが、ジブ様が言われていることは
「消したと思っているはずのC画面のインスタンスが
 実は残っている(B画面が掴んでいる)のでは?」
ということで解釈あっておりますでしょうか…?




どういう状況で起こっているのかわかりませんが
たとえば検索に時間がかかって、ボタンを2回押せてしまって
C画面が2枚開いてしまうとか。。。。

ともかく、予想していない状況になっていそうですよね。


引用:

B画面が閉じられたとき(=B画面上で「A画面へ戻る」ボタンが
クリックされたとき)、C画面へAddhandlerしたイベントハンドラをリムーブ
するようにしようとすると、今の状態では、
C画面のインスタンスを生成する際に
B画面上の「C画面を開く」ボタンのクリックイベント内で
C画面オブジェクトのスコープをローカル変数(Dim)で生成しているため、
B画面が閉じられたとき(=B画面上で「A画面へ戻る」ボタンがクリックされたとき)
のイベント内ではRemoveHandlerできないです…。
C画面オブジェクトのスコープをローカル変数としているところから
既に間違っているのでしょうか…。



イベントを待っている状況なわけですから、最後まで責任をもってあげないといけないだろうなと私は思います。

C画面が1枚だけしか開かない仕様であれば、インスタンスを保持する変数を準備してCloseイベントでNothingをセットしてあげるというのがよいように思います。
また、万が一プログラムミスでNothingでない状況からNewしようとした場合に例外をスローするとか安全なプログラムを書けば、原因不明な現象に悩まされる事態も減少するのではないだろうかと思います。

どういうきっかけで問題の現象が発生するのか私にはわかりません。
結果からだけ見ての直感的な意見ですので、ご容赦を。

スキルアップ/キャリアアップ(JOB@IT)