2012-11-23 16 views
5

CloseReasonに基づいて、FormClosingイベントを別の方法で処理するフォームがあります。たとえば、フォームを最小化するCloseReason.UserClosing WCFサービスコールから特定の値が返されたときにイベントをプログラムで呼び出すのですが、通知アイコンのコンテキストメニューItemClickedイベントからApplication.Exit()を呼び出して、他の条件でアプリケーションを終了します。Application.Exit()がFormClosingイベントを発生させないケースはありますか?

Application.Exit()が呼び出されたときにいつも私のアプリが期待通りに機能していましたが、いつもFormClosingイベントを起こしていましたが、何らかの変更を加えてもそのようには動作しません。ほとんどの場合、イベントを発生させることなくアプリケーションが終了し、フォームを終了することなく、イベントのコードが呼び出される回数が実行されます(データベース作業、通知アイコンの廃棄)。

どうすればいいですか? Application.Exit方法は、あなたのアプリケーションを終了するために呼び出されたとき

+0

'ShowInTaskbar = false;'のとき、 'Application.Exit()'は通常はそうであるときに 'FormClosing'イベントをトリガーしませんでした。 –

答えて

11

はい、可能です。 Application.Exit()メソッドは、OnFormClose()メソッドを呼び出すようにApplication.OpenFormsコレクションのフォームを繰り返します。 Winformsには、そのコレクションがオープンフォームを追跡できないバグがあります。このコードはそれを示しています:

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
    } 
    protected override void OnHandleCreated(EventArgs e) { 
     // Set breakpoint here: 
     base.OnHandleCreated(e); 
    } 
    protected override void OnMouseDown(MouseEventArgs e) { 
     this.ShowInTaskbar = !this.ShowInTaskbar; 
     MessageBox.Show(string.Format("There are {0} open forms", Application.OpenForms.Count)); 
     Application.Exit(); 
    } 
    protected override void OnFormClosing(FormClosingEventArgs e) { 
     MessageBox.Show("you won't see this"); 
     base.OnFormClosing(e); 
    } 
} 

フォームをクリックすると、バグが発生します。どのようにそれが0の開いたフォームを報告し、OnFormClosingで表示されたメッセージボックスを見たことがないことに注意してください。

ShowInTaskbarプロパティに割り当てられます。このようなプロパティがいくつかありますが、NotifyIconを使用しているときに使用する可能性があるため、ShowInTaskbarを選択しました。 RightToLeftは別のものです。これらのプロパティは、ネイティブのCreateWindowEx()API関数を使用してウィンドウを作成した場合にのみ指定できるため、特殊です。それらを変更するには、Winformsがかなり英雄的な何かをする必要があります、それはウィンドウを破壊し、それを再作成します。残念なことにこれもバグを引き起こし、ウィンドウを破壊するとOpenFormsコレクションからフォームが削除され、それを元に戻すことは忘れてしまいます。

OnHandleCreated()メソッドをこのスニペットからフォームにコピー/ペーストし、ブレークポイントを設定します。ウィンドウが最初に作成されると、それは一度トリガーする必要があります。それが再びトリガされ、バグのシナリオが呼び出されると、呼び出しスタックを調べて、クラス内のどのコードがトリガされたかを確認できます。そのコードを無効にして、別の方法でコードを実行する必要があります。コンストラクターでShowInTaskbarプロパティーを設定しても問題ありませんが、Loadイベントハンドラーのように、ウィンドウが作成された後に割り当てられた場合にのみ問題になります。

+0

ありがとう、それは私が実際に行った変更です。 'ShowInTaskbar'プロパティは、' FormLoad'イベントの最後にtrueに設定していますが、アプリケーションのロード中に完了する必要があります。私はそれを調べます。 – Pantelis

+0

他にどのようなプロパティが発生する可能性がありますか?私はFormLoadイベントからプロパティを設定を削除し、それがまだ発生します。しかし、それほど頻繁ではありませんが、10回に1回もそうですが、それでも起こります。 – Pantelis

+0

いくつかの奇妙な球のコーナーケースがあります。このため、OnHandleCreatedメソッドでブレークポイントを使用してデバッグすることをお勧めします。 –

1

だけでなく、stated here

Form.ClosedとForm.Closingイベントは発生しません。 これらのイベントのいずれかで実行する必要がある検証コードがある場合は、 Exitメソッドを呼び出す前に、開いているフォームごとにForm.Closeメソッドを個別に呼び出す必要があります( )。

EDIT

あなたが、その場合には、FormClosingを使用しているので、多分あなたは、終了をキャンセルし、さらに問題を調査に役立つ形を決定するのに役立つかもしれないExitのオーバーロードを使用してみてください。

+0

プロジェクトにはいくつかのセカンダリフォームがありますが、いずれも開いていません。また、私は廃止されたClosingイベントを呼び出さない。私はFormClosingイベントを呼び出しています。 – Pantelis

+0

終了は非常にまれにキャンセルされています。大部分の時間、メインフォームのFormClosingイベントを発生させることなく、Appは終了します。 – Pantelis

+0

@Pantelis、まだobselete WinFormsを使っています。 – Jodrell

関連する問題