- - PR -
画面遷移時に表示順が変わるのを防ぎたい
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-11-18 19:23
開発環境
OS:WindowsXP Pro SP1 DB:Oracle10g(ODP.Net10.1.0.3使用) ツール:VB.NET2003 + .NetFramework1.1 SP1 実行環境 OS:Windows2000 SP4,WindowsXP Pro SP2 ODP.Net10.1.0.3 + .NetFramework1.1 SP1をインストール済 現在、上記の環境でWindowsアプリの開発を行なっております。 画面が3つあり(A,B,Cとします)、 A画面→B画面→C画面というように画面遷移をさせています。 A画面で「B画面へ遷移」ボタンをクリックすると そのクリックイベントの中で Dim frmB As formB frmB = New formB() AddHandler frmB.Closed, AddressOf Close_frmB frmB.Show() Me.Hide() と記述し、 1.B画面のインスタンス作成 2.B画面が閉じられたときのイベント追加 3.B画面を表示 4.A画面を隠す という処理を行っています。 次にB画面でも同じように「C画面へ遷移」ボタンをクリックすると そのクリックイベントの中で 1.C画面のインスタンス作成 2.C画面が閉じられたときのイベント追加 3.C画面を表示 4.B画面を隠す というソースコードを記述しています。(ソースコードは上記と同じです) これでC画面を表示し、C画面で「B画面へ戻る」ボタンをクリックしたとき ボタンのクリックイベントには Me.Close() と記述し、C画面を閉じています。 ただこのとき、B画面側でC画面を呼ぶときに作成した 「2.C画面が閉じられたときのイベント追加」イベントが走ります。 B画面で記述しているC画面が閉じられたときのイベントには Me.Visible = True と記述しており、C画面が閉じられたらB画面を表示すると いうようにしています。 これと同じことをA画面でも行なっており、 B画面が閉じられたらA画面を表示すると記述しています。 これで、プログラムを起動させ、 A画面→B画面→C画面→B画面→A画面 というような操作を繰り返し行なっていると ときどき下記のような現象が発生します。 1.C画面を閉じた後にA画面が前面に来て、 B画面が背面になる。 2.C画面を閉じた後にA画面が前面に来て、 前回表示されていたC画面が背面に表示される(残っている)。 (A1→B1→C1→B1→A1→B2→C2→A1(背面にC1画面)) これを防ぎ、必ずA1→B1→C1→B1→A1→B2→C2→B2→A1 というサイクルが行なわれるようにしたいのですが 何が原因でこのような現象が起こっているのか分からず、 防止策が取れずにいます。 (毎回必ず起こるわけではなく、時々忘れた頃に発生します。) もし何かご存知のことなどありましたら ぜひ教えてください。よろしくお願い致します。 | ||||||||
|
投稿日時: 2005-11-18 22:06
ウィザードのようなインターフェースを作ろうとしているんだろうけれど、作り方が悪いです。画面上にPanelを配置、Panel上にコントロールを配置し、ウィザードの進行状況に合わせてPanelのVisibleプロパティをTrue/Falseにして画面を切り替えます。
| ||||||||
|
投稿日時: 2005-11-18 22:21
お返事ありがとうございます。
ウィザードというイメージではないのですが、 実際には、 A画面がメニュー画面 B画面が商品検索画面 C画面が商品検索結果画面 という作りになっております。 (初回の投稿では書かなかったのですが、 実際の業務アプリを作っており、 メニュー画面にはボタンが30個ほどあり、 画面数は50本ぐらいです。) メニュー画面で「商品検索」ボタンをクリックすると 商品検索画面を開き(showメソッド使用)、 メニュー画面を隠します(hideメソッド使用)。 商品検索画面で商品分類などを選択し、「検索開始」ボタンをクリックすると 商品検索結果画面を開き(showメソッド使用)、 商品検索画面を隠します(hideメソッド使用)。 商品検索結果画面で、「検索画面に戻る」ボタンをクリックすると 商品検索結果画面を閉じ(closeメソッド使用) 商品検索画面の中の「商品検索結果画面が閉じられたとき」のイベントを 利用して、商品検索画面を表示します(visibleプロパティ使用)。 このような業務アプリの場合でも パネルで切り替えるのが一般的なのですかね…。 1つ1つ画面(フォーム)を作って、 それを見せたり見せなかったり(開いたり閉じたり)して 切り替えるのが普通だと思っていました…。 もうすでに大半が作り終わってしまっているため 今からパネルに変更するのは修正規模が大きいため 他に何か良い方法や、作り方でまずい点などがありましたら ぜひ教えてください!! よろしくお願い致します。 | ||||||||
|
投稿日時: 2005-11-18 23:34
んー、いまいちわからないのですが。
こうゆうことですよね?(長くなるのでイベントハンドラの引数は省略してます)
自分の環境だと、
みたいな現象は発生しないです。 なぜなら、2つの画面が同時に表示されているという状態が無いので。 私、何か勘違いしてるのでしょうか | ||||||||
|
投稿日時: 2005-11-19 02:02
お返事ありがとうございます。
作成していただきましたソースで合っています。 私もそのように作成しています。 ぼのぼの様が投稿の最後に書かれておられますように、 画面が同時に2つ表示されていることは私もありません。 ただ頻繁に画面の順番が入れ替わるわけではなく、 使っていたら時々そういうことが発生するというぐらいで 起こったときの状況(検索に使用した値など)もバラバラで統一性がなく、 余計に原因が分からず、苦戦しております…。 また何かありましたらぜひ教えてください。 よろしくお願い致します。 | ||||||||
|
投稿日時: 2005-11-19 06:38
これ、Close_frmB メソッドを持っているのは、どの画面ですか?B画面じゃないですか?B画面のメソッドで、Me.Close ってやったら、Me はB画面なんじゃないですか? Form って、IDisposable … MustDispose なんですけど、Close って、Dispose と同等でしたっけ?ShowModal があるので、なんか、ややこしかったような? ___________________________________________________________________ □ written by Jitta on 2005/11/19 □ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2005-Sept.2006 _________________ | ||||||||
|
投稿日時: 2005-11-21 20:19
お返事ありがとうございます。
----------------------------------------------------------------------- これでC画面を表示し、C画面で「B画面へ戻る」ボタンをクリックしたとき ボタンのクリックイベントには Me.Close() と記述し、C画面を閉じています。 ----------------------------------------------------------------------- 上記の件ですが、 Me.Close としているのは C画面の中にある「B画面へ戻る」ボタンのClickイベントです。 ですので、閉じられるのはC画面になります。 で、そのC画面が閉じられたときに、 B画面の「C画面が閉じられたとき」メソッドが動作して B画面をVisible=Trueで表示させています。 CloseとDisposeについてですが、 ShowDialogメソッドで開いたFormについては 明示的にDisposeしなければいけませんが、 Showメソッドで開いたFormについては Closeすれば自動的にDisposeも行なわれます。 こうやったら必ず現象が発生するというわけではないので 再現させたくても再現できず、非常につらい状況です。 またもし何かありましたらぜひ教えてください。 よろしくお願い致します。 | ||||||||
|
投稿日時: 2005-11-24 21:39
同現象が発生し、そのときのエラーが
分かりましたので書き込みをさせていただきます。 A画面→B画面→C画面まで開き、 (このとき、A画面とB画面は隠れている状態) C画面で「B画面へ戻る」ボタンをクリックすると 以下のエラーメッセージが表示されました。 「”B画面”という名前の、破棄されたオブジェクトに アクセスできません。 オブジェクト名:”B画面”です。」 エラーはSystem.ObjectDisposedExceptionが発生しています。 私が実際に書いているソースコードは ぼのぼの様が書いてくださっているソースコードと まったく同じです。 そこで、1つ気になる点があるのですが、 B画面クラス(Public Class FormB)の中で、 B画面からC画面のインスタンスを生成し、 自分自身(B画面)を隠し、 Button1_Clickイベントを終えたとき(End Sub)、 この生成したC画面オブジェクト(frmC)は 自動的に破棄されますよね。 (正確には、破棄してもいいですよという状態で メモリ上にはまだ残っていて、 ガーベジコレクション機能が働いたときに 実際にメモリ上から開放されると認識しております。) この状態で、生成されたC画面(今表示されているC画面)の親画面は 隠れているB画面であるというこのつながりが 正しく保持されているのかということが気になっています。 全然的外れなことを言っているかもしれませんが、 何か原因がつかめる糸口になればと思います。 また、何かありましたらぜひ教えてください。 よろしくお願い致します。 |