FormClosing
イベントを使用すると、コードはe.Cancel = true;
機能するのに機能しないのはなぜnew CancelEventArgs().Cancel = true;
ですか?
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
new CancelEventArgs().Cancel = true;
}
FormClosing
イベントを使用すると、コードはe.Cancel = true;
機能するのに機能しないのはなぜnew CancelEventArgs().Cancel = true;
ですか?
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
new CancelEventArgs().Cancel = true;
}
このイベントは、Winforms配管コードによって発生します。カスタムイベントハンドラーがデフォルトの動作を変更したいことを確認できる唯一の方法は、e
オブジェクトを使用することです。新しいCancelEventArgsオブジェクトを作成しても、配管で検出できる副作用はありません。
他に何か問題があります。外部コードの利益のためにイベントが発生し、何が起こっているのかを知らせ、動作を変更するオプションを提供します。ここには外部コードはありません。イベントハンドラーは、実際にはイベントを発生させる同じクラスの一部です。つまり、フォームは独自のイベントをリッスンしています。これに対処するためのはるかに優れた方法があります。イベントを発生させるメソッドをオーバーライドします。このような:
protected override void OnFormClosing(FormClosingEventArgs e) {
e.Cancel = true;
base.OnFormClosing(e);
}
これで、外部コードがデフォルトの動作をオーバーライドできるようになり、OnXxxxメソッドの実行後にイベントが発生します。また、外部コードで動作をオーバーライドしたくない場合は、2つのステートメントを入れ替えるだけです。
コードはそれが言っていることを正確に実行していると思います。欠けているのはそれを文字通り読むことです。
に新しい値を割り当てると、関数のパラメーターとして提供されるをe.Cancel
変更することになります。e
イベントハンドラー関数が終了FormClosingEventArgs
すると、イベントハンドラー内から加えられた変更を含め、このインスタンスは、イベントハンドラーを呼び出したすべてのコードで使用できるようになります。この場合、それはほぼ確実にMicrosoftによって作成されたWinformsコードです。
反対に、そのイベントハンドラー内でその型の新しいインスタンスを作成し、FormClosingEventArgs
それに何かを行うと、その情報を呼び出し元に返すことはできません。そのためには何か明確なものが必要です。呼び出し元は、イベントハンドラーが完了すると渡されたパラメーターの値を確認しているため、呼び出し元からe
見た内容を新しく作成されたインスタンスに置き換える必要があります。その他の場合、そのような結果は戻り値として提供される場合があります。
一般に、new T()
あるタイプのの結果は、タイプT
のインスタンスですT
。new T()
したがって、型のnull以外の変数と同じように、式の結果を操作できますT
。T
特定のケースでは、タイプのプロパティ(具体的には、このように作成されたタイプのインスタンス)に値を割り当てています。(コンストラクターが失敗する特殊なケースがありますが、今はそこに行きません。単純な型の場合、それは、プログラムがどのような場合でも実行を継続できないほどの悲惨な状況にあることを意味します。 )。
new T()
ここで重要なのは、式自体の結果をどこにも割り当てない場合、ステートメントが完了すると、新しく作成されたインスタンスが破棄される(技術的にはアクセスできなくなる)ことです。その後、ある時点で、.NETガベージコレクタが起動し、割り当てられたメモリを実際に再利用します。ここを除いて、ある関数に変数を割り当て、別の関数からその関数を呼び出し、最初の関数から2番目の関数に変数を転送することなく、2番目の関数から割り当てられた変数にアクセスしようとすることと実際には何の違いもありません。関与する機能は1つだけです。
イベントハンドラーで2行目のコードのようなことを行うのはかなり珍しいことですが、コンストラクターを呼び出すことで、遅延読み込みのトリガーなど、利用しようとしている副作用がある場合は、原則として有効です。
このコードは確かに機能します
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (PreClosingConfirmation() == System.Windows.Forms.DialogResult.Yes)
{
Dispose(true);
Application.Exit();
}
else
{
e.Cancel = true;
}
}
private DialogResult PreClosingConfirmation()
{
DialogResult res = System.Windows.Forms.MessageBox.Show(" Do you want to quit? ", "Quit...", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
return res;
}
ハッピーコーディング
これCancelEventArgs
は、コード内のイベント ハンドラーに渡されるオブジェクト参照であるためです。舞台裏のコードがオブジェクトで発生FormClosing
し、CancelEventArgs
すべてのイベント ハンドラーが同じオブジェクトを受け取ります。すべてのハンドラーの順番が回ったら、バックグラウンド コードがCancelEventArgs
送信したオブジェクトをチェックして、そのCancel
プロパティが に設定されているかどうかを確認しますtrue
。そうであれば、何もせず、FormClose
一連のイベントが停止します。Cancel
がfalse
(CancelEventArgs
既定値) の場合、つまりイベントCancel
チェーンに設定されていない場合、舞台裏のコードが処理され、FormClosed
イベントが発生します。
詳細については、MSDN の Form.FormClosing Event を参照してください。
通常、Forms
すべての -ing イベントの後に -ed イベントが続きます。-ing イベントには通常 がありCancelEventArgs
、そのCancel
プロパティを に設定しtrue
て -ed イベントの発生を停止できます。