Przycisk Escape, aby zamknąć formularz Windows Forms w C #

93

Próbowałem następujących rzeczy:

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

Ale to nie działa.

Potem spróbowałem tego:

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

I nadal nic nie działa.

KeyPreview we właściwościach formularza Windows Forms jest ustawiona na true ... Co robię źle?

yeahumok
źródło
1
Czy próbowałeś ustawić punkt przerwania w tych metodach? Czy program obsługi zdarzeń w ogóle działa?
Steve Danner
1
Nie nazywaj swojego przycisku anulowania jak właściwość formularza „CancelButton”. W przeciwnym razie wydaje się, że nie można ustawić przycisku CancelButton.
Jonas Middendorf
@SteveDanner, zdarzenie nie jest wyzwalane. prawdopodobnie brakuje deklaracji w InitializeComponent ().
InfantPro'Aravind '12
Myślę, że powodem, dla którego to nie działa, jest to, że inne kontrolki w formularzu mają fokus ...
itsho

Odpowiedzi:

199

To zawsze będzie działać niezależnie od prawidłowego przyporządkowania obsługi zdarzeń, KeyPreview, CancelButtonitp:

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
źródło
10
-1, użycie właściwości CancelButton formularza jest poprawnym sposobem.
ABCD
14
Ugh, dzwonili z lat 80-tych, chcą odzyskać swoje okno dialogowe.
Hans Passant
1
Możesz także powrócić truez, ProcessCmdKeyaby zasygnalizować, że klucz jest zajęty, zapobiegając w ten sposób dźwiękowi „ding”.
Spooky
8
Możesz użyć właściwości CancelButton formularza tylko wtedy, gdy formularz zawiera rzeczywisty Button (lub obiekt interfejsu IButtonControl).
David
3
Ta opcja jest dobra. CancelButton wymaga dodatkowego widocznego przycisku „Anuluj” w formularzu. To jest redundantne renderowanie + kod + itd.
V319,
64

Powinieneś być w stanie ustawić właściwość formularza na CancelButtonprzycisk Anuluj, a wtedy nie będziesz potrzebować żadnego kodu.

Shawn Steward
źródło
2
Zrobiłem to, ale nie jest zwolniony, kiedy naciskam klawisz esc, dlaczego?
Mihai Bratulescu
To działało świetnie dla mnie. Znacznie lepiej dla małych form.
knut
15

Zakładając, że masz przycisk „Anuluj”, ustawienie właściwości formularza CancelButton(w projektancie lub w kodzie) powinno zająć się tym automatycznie. Po prostu umieść kod do zamknięcia w Clickprzypadku przycisku.

Adam Robinson
źródło
9

Przyjęta odpowiedź jest rzeczywiście prawidłowa i kilkakrotnie użyłem tego podejścia. Nagle to już nie działało, więc wydało mi się to dziwne. Głównie dlatego, że mój punkt przerwania nie zostałby trafiony dla ESCklawisza, ale uderzyłby w inne klawisze.

Po debugowaniu stwierdziłem, że jedna z kontrolek z mojego formularza przesłaniała ProcessCmdKeymetodę z tym kodem:

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

... i to uniemożliwiało mojemu formularzowi uzyskanie ESCklucza (zwróć uwagę na return true). Dlatego upewnij się, że żadne elementy sterujące podrzędne nie przejmują danych wejściowych.

Joel
źródło
Nie wiem, czy w formularzu
KeyPreview
Wydaje się, że napotykam ten problem z kontrolkami ListView na moim winform. Zastanawiam się, czy to ListView, w którym również zauważyłeś problem?
raddevus
2

Ustawiasz KeyPreview na true w opcjach formularza, a następnie dodajesz do niego zdarzenie Keypress. W zdarzeniu naciśnięcia klawisza wpisz:

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

key.Char == 27 to wartość ucieczki w kodzie ASCII.

Kristian
źródło
To dobre obejście problemu. Mam formularz z kontrolkami ListView iw takim przypadku wydają się połykać CancelButton (po naciśnięciu klawisza Esc). Dodałem ten kod i rozwiązałem problem.
raddevus
0

Przez przycisk Escape masz na myśli klawisz Escape? Sądząc po twoim kodzie, myślę, że tego chcesz. Możesz także spróbować Application.Exit (), ale Close powinno działać. Czy masz wątek roboczy? Jeśli działa wątek niebędący w tle, może to spowodować, że aplikacja będzie otwarta.

SwDevMan81
źródło
0

Musisz dodać to do zdarzenia „KeyUp”.

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if(e.KeyCode == Keys.Escape)
        {
            this.Close();
        }
    }
Dawid Bobyla
źródło
0

Możesz także aktywować inną formę.

Np. Wyzwalaj przycisk Anuluj, jeśli edytujesz właściwość CancelButton formularza i ustawisz przycisk Anuluj.

W kodzie traktujesz przycisk Anuluj w następujący sposób, aby zamknąć formularz:

    private void btnCancel_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.Abort;
    }
webMac
źródło