C#でWindowsフォームフォームを閉じるエスケープボタン


91

私は以下を試しました:

private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
    if ((Keys) e.KeyValue == Keys.Escape)
        this.Close();
}

しかし、それは機能しません。

それから私はこれを試しました:

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    if (e.KeyCode == Keys.Escape)
        this.Close();
}

そして、まだ何も機能していません。

WindowsフォームのフォームプロパティのKeyPreviewがtrueに設定されています...何が問題なのですか?


1
これらのメソッドにブレークポイントを設定してみましたか?イベントハンドラーは発火していますか?
スティーブダナー

1
キャンセルボタンにフォームプロパティ 'CancelButton'のような名前を付けないでください。それ以外の場合は、CancelButtonを設定できないようです。
Jonas Middendorf、2011

@SteveDanner、イベントはトリガーされません。おそらくInitializeComponent()の宣言が欠落しています。
InfantPro'Aravind '

それが機能しない理由は、フォーム内の他のコントロールがフォーカスを取得したためです...
itho

回答:


199

これは、適切なイベントハンドラーの割り当て、KeyPreview、CancelButtonなどに関係なく、常に機能します。

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == Keys.Escape) {
            this.Close();
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

10
-1、フォームのCancelButtonプロパティの使用が正しい方法です。
ABCD

14
うーん、1980年代に呼ばれた、彼らはダイアログボックスを元に戻したいです。
ハンスパッサント2013

1
trueから戻っProcessCmdKeyてキーが処理されたことを通知することもできるため、「ノイズ」ノイズを防止できます。
不気味な

8
フォームにCancelButtonプロパティを使用できるのは、フォームに実際のButton(またはIButtonControlインターフェイスオブジェクト)がある場合のみです。
David

3
このオプションは良いです。CancelButtonには、フォームに追加の表示されている「キャンセル」ボタンが必要です。これは冗長なレンダリング+コード+など
V319

64

フォームのCancelButtonプロパティを[キャンセル]ボタンに設定できれば、コードは必要ありません。


2
私はそれをしましたが、Escキーを押しても起動しません、なぜですか?
Mihai Bratulescu 2014年

これは私にとってはうまくいきました。小さなフォームにはずっと良いです。
knut 2016

15

「キャンセル」ボタンがあると仮定すると、フォームのCancelButtonプロパティを(デザイナーまたはコードで)設定すると、これが自動的に処理されます。Clickボタンのイベントで閉じるコードを配置するだけです。


9

確かに受け入れられた答えは正しいです、そして私はそのアプローチを数回使用しました。突然、動作しなくなったので不思議に思いました。ほとんどの場合、私のブレークポイントはESCキーにはヒットしませんが、他のキーにはヒットします。

デバッグした後ProcessCmdKey、次のコードを使用して、フォームのコントロールの1つがメソッドをオーバーライドしていることがわかりました。

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // ...
    if (keyData == (Keys.Escape))
    {
        Close();
        return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

...これにより、フォームがESCキーを取得できなくなりました(に注意してくださいreturn true)。したがって、子コントロールが入力を引き継がないことを確認してください。


私の頭の上、オフではないあなたがtrueに設定されたフォームのKeyPreviewのに必要がある場合- msdn.microsoft.com/en-us/library/...
Andez

WinformのListViewコントロールでこの問題が発生しているようです。あなたも問題を見たのはListViewなのでしょうか?
raddevus

1

フォームオプションでKeyPreviewをtrueに設定し、それにKeypressイベントを追加します。keypressイベントで、次のように入力します。

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == 27)
    {
        Close();
    }
}

key.Char == 27 ASCIIコードでのエスケープの値です。


これは、この問題に対する適切な回避策です。ListViewコントロールを含むフォームがあり、その場合、(Escが押されたときに)それらがCancelButtonを飲み込むように見えます。このコードを追加して問題を修正しました。
raddevus

0

エスケープボタンとは、エスケープキーを意味しますか?あなたのコードから判断すると、私はそれがあなたが望んでいることだと思います。Application.Exit()を試すこともできますが、Closeが機能するはずです。ワーカースレッドはありますか?非バックグラウンドスレッドが実行されている場合、アプリケーションが開いたままになる可能性があります。


0

これをイベント「KeyUp」に追加する必要があります。

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if(e.KeyCode == Keys.Escape)
        {
            this.Close();
        }
    }

0

他のフォームをトリガーすることもできます。

たとえば、フォームのCancelButtonプロパティを編集してボタンのキャンセルを設定すると、キャンセルボタンがトリガーされます。

コードでは、キャンセルボタンを次のように扱い、フォームを閉じます。

    private void btnCancel_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.Abort;
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.