C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.76951 の関連記事表示

<< 0 >>
■76951  WinCEのDialogResultのイベント順序について
□投稿者/ トシ -(2015/08/31(Mon) 14:22:52)

    分類:[VB.NET/VB2005 以降] 

    2015/08/31(Mon) 14:48:41 編集(投稿者)
    2015/08/31(Mon) 14:47:48 編集(投稿者)

    動作OS
    Windows Embedded Compact 7

    開発環境
    Microsoft Windows 7 SP1
    Microsoft Visual Studio 2008 (VB.netを使用)
    .Net Compact Framework 3.5

    質問内容
    モーダルダイアログボックスの DialogResult と FormClosing イベントの関係について

    本題
     他に質問する場所もなく、こちらにてはじめて質問させていただきます。
    どうぞよろしくお願いいたします。
     
    作成した簡易プログラム
    '--- Form1 --- Buttonコントロールを1個配置
    Public Class Form1
    Private Sub Button1_Click( sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim ret As DialogResult
    Debug.WriteLine( "Form1:Click Start" )
    Using wForm As Form = New Form2
    ret = wForm.ShowDialog
    End Using
    Debug.WriteLine( "Form1:Click End" )
    End Sub
    End Class

    '--- Form2 --- Buttonコントロールを1個配置
    Public Class Form2
    Private Sub Button1_Click( sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Debug.WriteLine( " Form2:Click Start" )
    Me.DialogResult = Windows.Forms.DialogResult.Yes '-- テスト1
    Me.DialogResult = Windows.Forms.DialogResult.No '-- テスト2 2度セットしていることに意味はありません。
    Debug.WriteLine( " Form2:Click End" )
    End Sub

    Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    Debug.WriteLine( " Form2:Closing Start" )
    Debug.WriteLine( " Form2:Closing End" )
    End Sub
    End Class


    上記テストプログラムを作成しました。
    動作内容は
    @プログラムを起動
    AForm1 のボタンを押して Form2 を開く
    BForm2 のボタンを押して、Form2 を閉じる
    を行っています。

    この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。

    Windows 7 SP1
    Form1:Click Start
    Form2:Click Start
    Form2:Click End ※注目
    Form2:Closing Start ※注目
    Form2:Closing End ※注目
    Form1:Click End

    Windows Embedded Compact 7
    Form1:Click Start
    Form2:Click Start
    Form2:Closing Start ※注目 DialogResult.Yes 設定タイミング
    Form2:Closing End ※注目
    Form2:Closing Start ※注目 DialogResult.No 設定タイミング
    Form2:Closing End ※注目
    Form2:Click End ※注目
    Form1:Click End

    上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
    なぜこのようなことが起きているのかは不明ではありますが、
    どのような対応をするのが正しい(よりベスト)なのかがわかりません。
    ※実は、この動作によって、フォームが正しく終了していないような動作が
    発生しているようなのです。(2度めのFormClosing Endで停止)

    お分かりになる方がおりましたら、アドバイスを頂ければと思います。
    何卒よろしくお願いいたします。
親記事 /過去ログ130より / 関連記事表示
削除チェック/

■76953  Re[1]: WinCEのDialogResultのイベント順序について
□投稿者/ Hongliang -(2015/08/31(Mon) 14:59:41)
    > 上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
    > なぜこのようなことが起きているのかは不明ではありますが、

    そういうものとしか言いようがないような。
    ターゲットがWindowsとWindows CEという別のOSである以上、実装に差異があるのは当然でしょう。

    > どのような対応をするのが正しい(よりベスト)なのかがわかりません。

    DialogResultを一度きりしか設定しないようにすれば良いんじゃないでしょうか。
    不正終了する動作は.NET Compact Frameworkのバグかもしれませんが、
    それをMSに報告したところで今更.NET Compact Framework 3.5を修正するとも思えませんし。
記事No.76951 のレス /過去ログ130より / 関連記事表示
削除チェック/

■76954  Re[2]: WinCEのDialogResultのイベント順序について
□投稿者/ kiku -(2015/08/31(Mon) 15:15:51)

    環境はWindows Embedded Compact 7ではなく
    WindowsCE6.0ですが、
    同じ現象を確認しました。

    仕様として受け入れるしかなさそうです。
記事No.76951 のレス /過去ログ130より / 関連記事表示
削除チェック/

■76955  Re[3]: WinCEのDialogResultのイベント順序について
□投稿者/ トシ -(2015/08/31(Mon) 15:36:07)
    No76954 (kiku さん) に返信
    > 
    > 環境はWindows Embedded Compact 7ではなく
    > WindowsCE6.0ですが、
    > 同じ現象を確認しました。
    > 
    > 仕様として受け入れるしかなさそうです。
    
    
    HongLiang様 kiku様
    ご返信ありがとうございます。
    
    kiku様に至っては、確認までしていただきありがとうございます。
    お二人とも
    「仕様として受け入れるしかない」
    という意見で、私もその通りだとは思っています。
    上司が理由を知りたがるので、何かご存知または、ベストな情報をお持ちかと思い質問させていただきました。
    
    今回は
    
        Private ResultCode      As DialogResult = Windows.Forms.DialogResult.None
    
        Private Sub Button1_Click( sender As System.Object,  e As System.EventArgs) Handles Button1.Click
            Debug.WriteLine( "  Form2:Click Start" )
            ResultCode = Windows.Forms.DialogResult.Yes
            ResultCode = Windows.Forms.DialogResult.No
            Debug.WriteLine( "  Form2:Click End" )
            Me.Close
        End Sub
        
        Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Debug.WriteLine( "    Form2:Closing Start" )
            Me.DialogResult = ResultCode
            Debug.WriteLine( "    Form2:Closing End" )
        End Sub
    
    Microsoftの情報 https://msdn.microsoft.com/ja-jp/library/system.windows.forms.form.dialogresult(v=VS.100).aspx より
     〜 ユーザーが閉じるボタンをクリックしたときに DialogResult プロパティに割り当てられる値をオーバーライドするには、 〜
     〜 フォームの Closing イベントのイベント ハンドラーで DialogResult プロパティを設定します。            〜
    から、Closingイベントで設定することは認められていると判断し
    
    上記ソースのように、いったんプライベート変数に格納後、
    自分でクローズを行い、Closing イベント内で設定を行うこととします。
    
    ちなみに、この場合のログは
     Form1:Click Start
       Form2:Click Start
         Form2:Closing Start
         Form2:Closing End
       Form2:Click End
     Form1:Click End
    
    となります。
    ※Closingイベント内で設定する事で、Closingイベントが無限ループしそうで怖かったですが、
     発生しなかったので、何かしら対策されているものだと思います。
    
    ありがとうございました。
    
記事No.76951 のレス / END /過去ログ130より / 関連記事表示
削除チェック/

■76956  Re[1]: WinCEのDialogResultのイベント順序について
□投稿者/ 魔界の仮面弁士 -(2015/08/31(Mon) 15:39:18)
    2015/08/31(Mon) 16:13:21 編集(投稿者)

    No76951 (トシ さん) に返信
    > '--- Form2 --- Buttonコントロールを1個配置
    > Public Class Form1
    Form1 クラスなのに Form2…?


    > この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。
    .NET Compact Framework に Form.FormClosing イベントは無いはずです。
    (Form.Closing イベントなら、.NET / .NET Comapact の両方にあります)
    https://msdn.microsoft.com/ja-jp/library/system.windows.forms.form_events%28vs.90%29.aspx



    > 上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
    > なぜこのようなことが起きているのかは不明ではありますが、
    > どのような対応をするのが正しい(よりベスト)なのかがわかりません。

    DialogResult プロパティをセットしたときにフォームが閉じられるのは仕様です。
    (モーダルなら非表示になり、モードレスなら破棄されます)
    この点は、.NET Compact Framework でも .NET Framework でも同様です。

    違うのは、いつ閉じられるのかという「タイミング」の問題です。



    > この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。

    当方の実験結果:

    【.NET Compact Framework 3.5 App on Windows 7 Pro SP1 /w CLR 2.0】

    Form1:Click Start
     Form2:Click Start
     Form2:Click End
     Form2:Closing Start
     Form2:Closing End
    Form1:Click End

    【.NET Compact Framework 3.5 on Pocket PC 2003 SE エミュレータ】

    Form1:Click Start
     Form2:Click Start
     Form2:Closing Start
     Form2:Closing End
     Form2:Closing Start
     Form2:Closing End
     Form2:Click End
    Form1:Click End


    今度は、【.NET Framework 3.5 on Windows 7 Pro SP1】 で実験。
    ついでに、Application.Idle イベントが発生した時にもログを残しています。

    (Application.Idle)
    Form1:Click Start
    (Application.Idle)
     Form2:Click Start
     Form2:Click End
    (Application.Idle)
     Form2:Closing Start
     Form2:Closing End
    Form1:Click End
    (Application.Idle)


    Form1 の Button1_Click にせよ
    Form2 の Button1_Click にせよ
    Form2 の Form2_Closing にせよ、
    それらが開始されるのは、Application.Idle が呼ばれた後ということが分かります。

    また、Appliation.Idle になるのは、End Sub 通過後(あるいは、ShgowDialog 時)に
    限られます。これは、他の多くのイベントにおいても同じ動きです。


    デスクトップ OS においては、イベント処理が終わってアイドル時にならないと、
    Windows Message は基本的に処理されません。(実際に反映されるのは「End Subの後」です)
記事No.76951 のレス /過去ログ130より / 関連記事表示
削除チェック/

■76957  Re[2]: WinCEのDialogResultのイベント順序について
□投稿者/ トシ -(2015/08/31(Mon) 15:51:15)
    No76956 (魔界の仮面弁士 さん) に返信

    魔界の仮面弁士様
    ご返答ありがとうございます。
    よくお名前を拝見するので、いろいろ参考にさせていただいております。

    > ■No76951 (トシ さん) に返信
    >> '--- Form2 --- Buttonコントロールを1個配置
    >> Public Class Form1
    > Form1 クラスなのに Form2…?

    これについては申し訳ありません。
    後から気付いて修正いたしましたが、私の誤記です。



    >>この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。
    > .NET Compact Framework に Form.FormClosing イベントは無いはずです。
    > (Form.Closing イベントなら、.NET / .NET Comapact の両方にあります)
    > https://msdn.microsoft.com/ja-jp/library/system.windows.forms.form_events%28vs.90%29.aspx

    おっしゃる通り、Form.Closingが正しいです。


    >>上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
    >>なぜこのようなことが起きているのかは不明ではありますが、
    >>どのような対応をするのが正しい(よりベスト)なのかがわかりません。
    >
    > DialogResult プロパティをセットしたときにフォームが閉じられるのは仕様です。
    > (モーダルなら非表示になり、モードレスなら破棄されます)
    > この点は、.NET Compact Framework でも .NET Framework でも同様です。

    こちらの件につきましては、私のほうでもマイクロソフト社のページで拝見いたしました。
    当初、VB6の癖から Closeメソッド も書いてしまい、フォームクローズイベントが大量発生しました・・・
    ※今思えば、この時から後記していただいている「タイミング」による問題が発生していたことになります。



    > 違うのは、いつ閉じられるのかという「タイミング」の問題です。
    >
    >>この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。
    >
    > 当方の実験結果:
    >
    > 【.NET Compact Framework 3.5 on Windows 7 Pro SP1】
    >
    > Form1:Click Start
    >  Form2:Click Start
    >  Form2:Click End
    >  Form2:Closing Start
    >  Form2:Closing End
    > Form1:Click End
    >
    > 【.NET Compact Framework 3.5 on Pocket PC 2003 SE エミュレータ】
    >
    > Form1:Click Start
    >  Form2:Click Start
    >  Form2:Closing Start
    >  Form2:Closing End
    >  Form2:Closing Start
    >  Form2:Closing End
    >  Form2:Click End
    > Form1:Click End
    >
    > ということで、Compact Framework の仕様なのではなく、
    > デスクトップ系と CE 系の OS の動作の差違だと思います。
    >
    > 今度は、【.NET Framework 3.5 on Windows 7 Pro SP1】 で実験。
    > ついでに、Application.Idle イベントが発生した時にもログを残しています。
    >
    > (Application.Idle)
    > Form1:Click Start
    > (Application.Idle)
    >  Form2:Click Start
    >  Form2:Click End
    > (Application.Idle)
    >  Form2:Closing Start
    >  Form2:Closing End
    > Form1:Click End
    > (Application.Idle)
    >
    >
    > Form1 の Button1_Click にせよ
    > Form2 の Button1_Click にせよ
    > Form2 の Form2_Closing にせよ、
    > それらが開始されるのは、Application.Idle が呼ばれた後ということが分かります。
    >
    > また、Appliation.Idle になるのは、End Sub 通過後(あるいは、ShgowDialog 時)に
    > 限られます。これは、他の多くのイベントにおいても同じ動きです。
    >
    >
    > デスクトップ OS においては、イベント処理が終わってアイドル時にならないと、
    > Windows Message は基本的に処理されません。(実際に反映されるのは「End Subの後」です)


    つまり、CE系のOSでは、アイドル状態にならなくても、順次発生するべきイベントが発生している
    という認識でよろしいでしょうか?
    確かに、通常のWindowsアプリケーションでは、現在処理中の処理が完了(End Sub等)されるまで、
    開始されない状況であるのは認識おりました。
    もし、CE系ではこの点が違うとしたら、私は大きなミスをしてしまっているのかもしれません。
    全体的に見直してみる必要がありそうです・・・

    魔界の仮面弁士様、大変貴重な情報ありがとうございました。
記事No.76951 のレス / END /過去ログ130より / 関連記事表示
削除チェック/

■76959  Re[3]: WinCEのDialogResultのイベント順序について
□投稿者/ 魔界の仮面弁士 -(2015/08/31(Mon) 18:05:14)
    No76957 (トシ さん) に返信
    > つまり、CE系のOSでは、アイドル状態にならなくても、順次発生するべきイベントが発生している
    > という認識でよろしいでしょうか?

    あくまでも「DialogResult の場合は、即座に閉じられている」というだけですね。

    CE の場合、イベントの流れが異なっているものがあるのは確かですが、
    すべてのイベントがそういう動作になっているかどうかは別問題かと思います。


    なお DialogResult の setter 実装 を調べてみると、
    Compact では無い方の .NET Framework においては、
    |
    | Me.praivateな変数 = 新しいDialogResult値
    |
    という単純な処理しか行われていないようです。(参考: referencesource.microsoft.com )

    ゆえに、DialogResult をセットしてすぐに閉じるれることはなく、
    後から(アイドル時に)その変数が内部的に参照されることによって、
    閉じる処理に移行するという流れになるようです。
    (上記変数が None か否かが、各所でチェックされています)


    肝心の .NET Compact Framework については、ソースが公開されていないので
    詳しい調査はできませんが、DialogResult プロパティをセットしただけで
    即座に閉じられるという事は、内部フィールドの変更だけでなく、
    実際の閉じる処理まで一緒に行われるように実装されているのでしょう。多分。



    No76955 (トシ さん) に返信
    > ※Closingイベント内で設定する事で、Closingイベントが無限ループしそうで怖かったですが、
    >  発生しなかったので、何かしら対策されているものだと思います。

    対策されているかどうかが心配なら、標準の DialogResult を使うのはやめ、
    同等機能を持ったプロパティを独自に作ってみるとか。
記事No.76951 のレス /過去ログ130より / 関連記事表示
削除チェック/

■76962  Re[4]: WinCEのDialogResultのイベント順序について
□投稿者/ トシ -(2015/08/31(Mon) 18:49:03)
    No76959 (魔界の仮面弁士 さん) に返信
    >>※Closingイベント内で設定する事で、Closingイベントが無限ループしそうで怖かったですが、
    >> 発生しなかったので、何かしら対策されているものだと思います。
    > 対策されているかどうかが心配なら、標準の DialogResult を使うのはやめ、
    > 同等機能を持ったプロパティを独自に作ってみるとか。

    あー・・・
    確かに、プライベートな戻り値格納用変数用意するくらいなら
    それをパブリックなプロパティに変更して利用するのもありですね・・・

    ありがとうございます、参考にさせていただきます。

記事No.76951 のレス /過去ログ130より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -