Tombol Escape untuk menutup formulir Windows di C #

93

Saya telah mencoba yang berikut ini:

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

Tapi itu tidak berhasil.

Kemudian saya mencoba ini:

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

Dan masih tidak ada yang berhasil.

KeyPreview pada properti formulir Windows saya disetel ke true ... Apa yang saya lakukan salah?

yeahumok
sumber
1
Sudahkah Anda mencoba menyetel breakpoint dalam metode tersebut? Apakah event handler malah menembak?
Steve Danner
1
Jangan beri nama tombol batal Anda seperti properti formulir 'CancelButton'. Jika tidak, tampaknya Anda tidak dapat menyetel CancelButton.
Jonas Middendorf
@SteveDanner, acara tidak dipicu. mungkin deklarasi di InitializeComponent () tidak ada.
InfantPro'Aravind '
Saya pikir alasan itu tidak berhasil adalah karena kontrol lain di dalam formulir mendapat fokus ...
itsho

Jawaban:

199

Hal ini akan selalu bekerja, terlepas dari tugas event yang tepat, KeyPreview, CancelButton, dll:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
    if (keyData == Keys.Escape) {
        this.Close();
        return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}
Hans Passant
sumber
10
-1, penggunaan properti CancelButton Formulir adalah cara yang benar.
ABCD
14
Ugh, 1980-an disebut, mereka ingin kotak dialog mereka kembali.
Hans Passant
1
Anda juga dapat kembali truedari ProcessCmdKeyke sinyal bahwa kunci tersebut ditangani, sehingga mencegah derau "ding".
Seram
8
Anda hanya dapat menggunakan properti CancelButton formulir jika formulir memiliki Tombol sebenarnya di atasnya (atau objek antarmuka IButtonControl).
David
3
Pilihan ini bagus. CancelButton membutuhkan tombol 'Batal' tambahan yang terlihat pada formulir. Ini adalah render + code yang berlebihan + dll
V319
64

Anda hanya dapat mengatur CancelButtonproperti Formulir ke tombol Batal dan kemudian Anda tidak memerlukan kode apa pun.

Shawn Steward
sumber
2
Saya melakukan itu tetapi tidak ditembakkan ketika saya menekan esc, mengapa?
Mihai Bratulescu
Ini bekerja dengan baik untuk saya. Jauh lebih baik untuk bentuk kecil.
knut
15

Dengan asumsi bahwa Anda memiliki tombol "Batal", pengaturan CancelButtonproperti formulir (baik dalam perancang atau dalam kode) akan menangani ini secara otomatis. Cukup tempatkan kode untuk menutup Clickjika ada tombol.

Adam Robinson
sumber
9

Jawaban yang diterima memang benar, dan saya telah menggunakan pendekatan itu beberapa kali. Tiba-tiba, itu tidak berfungsi lagi, jadi saya merasa aneh. Sebagian besar karena breakpoint saya tidak akan mengenai ESCkunci, tetapi akan mengenai kunci lain.

Setelah debugging saya menemukan bahwa salah satu kontrol dari formulir saya adalah ProcessCmdKeymetode overriding , dengan kode ini:

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

... dan ini mencegah formulir saya mendapatkan ESCkunci (perhatikan return true). Jadi pastikan tidak ada kontrol anak yang mengambil alih masukan Anda.

Joel
sumber
Di luar kepalaku, tidak yakin apakah Anda perlu menyetel formulir KeyPreview ke true - msdn.microsoft.com/en-us/library/…
Andez
Saya tampaknya mengalami masalah ini dengan kontrol ListView di winform saya. Saya ingin tahu apakah ListView tempat Anda melihat masalahnya juga?
raddevus
2

Anda menyetel KeyPreview ke true dalam opsi formulir Anda dan kemudian Anda menambahkan acara Keypress ke dalamnya. Dalam acara penekanan tombol Anda, Anda mengetik yang berikut:

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

key.Char == 27 adalah nilai escape dalam kode ASCII.

Kristian
sumber
Ini adalah solusi yang bagus untuk masalah ini. Saya memiliki formulir dengan kontrol ListView di atasnya dan dalam hal ini mereka tampaknya menelan CancelButton (saat Esc ditekan). Saya menambahkan kode ini dan memperbaiki masalah.
raddevus
0

Yang Anda maksud dengan tombol Escape adalah tombol Escape? Menilai dari kode Anda, saya pikir itulah yang Anda inginkan. Anda juga dapat mencoba Application.Exit (), tetapi Close seharusnya berfungsi. Apakah Anda memiliki utas pekerja? Jika thread non-latar belakang sedang berjalan, ini dapat membuat aplikasi tetap terbuka.

SwDevMan81
sumber
0

Anda perlu menambahkan ini ke acara "KeyUp".

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

Anda juga dapat Memicu beberapa bentuk lain.

Misalnya memicu tombol Batal jika Anda mengedit properti Formulir CancelButton dan mengatur tombol Batal.

Dalam kode Anda memperlakukan Tombol Batal sebagai berikut untuk menutup formulir:

    private void btnCancel_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.Abort;
    }
webMac
sumber