Botão Escape para fechar o formulário Windows Forms em C #

91

Eu tentei o seguinte:

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

Mas não funciona.

Então eu tentei isso:

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

E ainda nada está funcionando.

O KeyPreview nas propriedades do formulário do Windows Forms está definido como verdadeiro ... O que estou fazendo de errado?

yeahumok
fonte
1
Você já tentou definir um ponto de interrupção nesses métodos? O manipulador de eventos está disparando?
Steve Danner
1
Não nomeie seu botão de cancelamento como a propriedade do formulário 'CancelButton'. Caso contrário, parece que você não pode definir o CancelButton.
Jonas Middendorf
@SteveDanner, o evento não é acionado. provavelmente a declaração em InitializeComponent () está faltando.
InfantPro'Aravind '12 de
Eu acho que a razão de não funcionar é porque outros controles dentro do formulário tiveram o foco ...
itsho

Respostas:

199

Isso sempre funcionará, independentemente da atribuição adequada do manipulador de eventos, KeyPreview, CancelButton etc:

    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
fonte
10
-1, o uso da propriedade CancelButton do Form é a maneira correta.
ABCD
14
Ugh, começaram os anos 1980, eles querem sua caixa de diálogo de volta.
Hans Passant
1
Você também pode retornar truede ProcessCmdKeypara sinalizar que a chave está manuseada, evitando assim o ruído "ding".
Assustador
8
Você só pode usar uma propriedade CancelButton do formulário se o formulário tiver um Button real nele (ou um objeto de interface IButtonControl).
David
3
Essa opção é boa. CancelButton requer um botão 'Cancelar' visível adicional no formulário. Isto é renderização + código + etc
redundante
64

Você deve apenas ser capaz de definir a CancelButtonpropriedade do Form para o botão Cancelar e então você não precisará de nenhum código.

Shawn Steward
fonte
2
Eu fiz isso, mas não é disparado quando pressiono esc, por quê?
Mihai Bratulescu
Isso funcionou muito bem para mim. Muito melhor para formulários pequenos.
knut
15

Supondo que você tenha um botão "Cancelar", a configuração da CancelButtonpropriedade do formulário (no designer ou no código) deve cuidar disso automaticamente. Basta colocar o código para fechar no Clickcaso do botão.

Adam Robinson
fonte
9

A resposta aceita de fato está correta, e usei essa abordagem várias vezes. De repente, não funcionava mais, então achei estranho. Principalmente porque meu ponto de interrupção não seria pressionado para a ESCtecla, mas sim para outras teclas.

Após a depuração, descobri que um dos controles do meu formulário estava substituindo o ProcessCmdKeymétodo, com este código:

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

... e isso estava impedindo meu formulário de obter a ESCchave (observe o return true). Portanto, certifique-se de que nenhum controle filho esteja controlando sua entrada.

Joel
fonte
Pensando bem
Andez
Parece que estou encontrando esse problema com os controles ListView no meu winform. Será que é no ListView que você viu o problema também?
raddevus
1

Você define KeyPreview como true nas opções de formulário e, em seguida, adiciona o evento Keypress a ele. No evento de pressionamento de tecla, você digita o seguinte:

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

key.Char == 27 é o valor de escape no código ASCII.

Kristian
fonte
Esta é uma boa solução para o problema. Eu tenho um formulário com controles ListView nele e, nesse caso, eles parecem engolir o CancelButton (quando Esc é pressionado). Eu adicionei este código e ele corrigiu o problema.
raddevus
0

Por botão Escape você quer dizer a tecla Escape? A julgar pelo seu código, acho que é o que você deseja. Você também pode tentar Application.Exit (), mas Close deve funcionar. Você tem um thread de trabalho? Se um thread não em segundo plano estiver em execução, isso pode manter o aplicativo aberto.

SwDevMan81
fonte
0

Você precisa adicionar isso ao evento "KeyUp".

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

Você também pode disparar alguma outra forma.

Por exemplo, acione um botão Cancelar se você editar a propriedade CancelButton do formulário e definir o botão Cancelar.

No código, você segue o botão Cancelar da seguinte maneira para fechar o formulário:

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