Pare o 'Ding' ao pressionar Enter

124

Eu tenho um aplicativo Windows Forms muito simples. E, no Windows (ou pelo menos nos Windows Forms Applications), quando você pressiona Enter enquanto estiver dentro de um Controle TextBox de linha única, ouve um Ding. É um som desagradável, que indica que você não pode inserir uma nova linha, porque é uma caixa de texto de linha única.

Está tudo bem. No entanto, no meu formulário, tenho 1 TextBox e um botão de pesquisa. E estou permitindo que o usuário realize uma pesquisa pressionando Enter depois de terminar de digitar, para que não precisem usar o mouse para clicar no botão Pesquisar.

Mas esse som Ding ocorre. É muito irritante.

Como podemos fazer com que apenas o som não seja reproduzido no meu formulário?

@ David H - Aqui está como eu estou detectando o enter pressionando:

private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        // Perform search now.
    }
}
Bendr
fonte
Como você detecta que Enter foi pressionado quando o foco está na caixa de texto?
David Heffernan
No Painel de Propriedades, clique duas vezes no Evento KeyDown ou KeyUp. Então, na Visualização de código, você digita o código que estou prestes a colocar na minha pergunta para você.
bendr
2
KeyPress é provavelmente o evento certo, e que pretende definir e.Handled = true
David Heffernan
Obrigado, @ David, eu não sabia que este :)
bendr
7
Eu gostaria que houvesse alguma maneira de suprimir o toque irritante, mas permitir que a tecla seja pressionada. Às vezes, pressionar uma tecla é apenas uma tecla, sem necessidade de alarme.
flipdoubt

Respostas:

56

Confira a propriedade Form.AcceptButton . Você pode usá-lo para especificar um botão padrão para um formulário, neste caso, pressionando enter.

Dos documentos:

Essa propriedade permite que você designe uma ação padrão para ocorrer quando o usuário pressionar a tecla ENTER no seu aplicativo. O botão atribuído a esta propriedade deve ser um IButtonControl que esteja no formulário atual ou localizado em um contêiner no formulário atual.

Há também uma propriedade CancelButton para quando o usuário pressiona escape.

mdm
fonte
1
Obrigado @mdm, isso funcionou melhor para mim. :) Voltarei a votar quando tiver mais representantes.
bendr
1
@ Bendr eu tenho o mesmo problema .. mas estou usando UserControl .. ele não tem Form.AcceptButton .. como corrigi-lo?
Murhaf Sousli
1
O Visual Studio parece não ter um campo no painel Propriedades para isso. Isso tem que ser feito em código, aparentemente. this.AcceptButton = buttonOK; this.CancelButton = buttonCancel;
Chris
5
Isso não funcionará para ToolStripButtons ou se você desejar usar a tecla ENTER para validar um TextBox ou ToolStripTextBox. A melhor abordagem seria a resposta de Lucio Fonseca, que funcionou para mim com o ToolStripTextBox.
Robert S.
Eu não posso ver a sua solução você não tem um exercício prático para ser mais esclarecida
Pedro Ávila
197

Funciona para mim:

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{

    //Se apertou o enter
    if (e.KeyCode == Keys.Enter)
    {
        //enter key is down

        this.doSomething();

        e.Handled = true;
        e.SuppressKeyPress = true;

     }

 }

O SuppressKeyPress é realmente o truque. Espero que ajude você.

Lucio Fonseca
fonte
30
Esta é a única resposta válida, na minha opinião. e.Handled = true;foi insuficiente; foi o SuppressKeyPressque fez o truque.
Jonathon Reinhart
12
textBox1_KeyUp vai ding nesta situação, independentemente da manuseado ou SuppressKeyPress
stackuser83
4
Funciona para mim com ToolStripTextBox.KeyDown. Nenhuma outra solução fez. Obrigado!
Robert S.
1
Não funcionou para mim no meu textboxe KeyDownevento #
Alex Jolig
7
Essa deve ser a resposta aceita. A resposta atual aceita requer um botão padrão colocado no formulário que é desagradável.
Javid
56

Experimentar

textBox.KeyPress += new KeyPressEventHandler(keypressed);

private void keypressed(Object o, KeyPressEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        e.Handled = true; //this line will do the trick
    }
}
Panda de fogo
fonte
Correto, mas só funcionará se o foco ainda estiver no TextBox. E se o usuário pressionar Tabprimeiro?
Mdm
4
@mdm Depende do design da interface do usuário. Talvez o OP só queira essa ação quando o foco estiver na caixa de texto. Isso é bastante comum.
David Heffernan
2
Se o usuário pressionar Tab, o foco não estará mais no TextBox, o próximo Contorl que será Focado será o Controle de Botão, que não emitirá esse som quando você pressionar Enter. :-)
bendr
@ David, obrigado pelo seu exemplo. Eu apenas tentei. E sempre que eu coloco e.Handled = true no evento .KeyPress, nenhum outro código é executado. A única coisa que acontece é todo o texto na caixa de texto torna-se selecionado (e eu nem sequer têm código que seleciona qualquer texto)
bendr
1
A resposta de Lucio Fonseca foi a única que encontrei para cuidar do problema.
Jonathon Reinhart
15

Basta adicionar e.SuppressKeyPress = true;sua declaração "se".

private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        //If true, do not pass the key event to the underlying control.
        e.SuppressKeyPress = true;  //This will suppress the "ding" sound.*/

        // Perform search now.
    }
}
brandonstrong
fonte
13

Você pode usar o KeyPress em vez do KeyUp ou KeyDown, é mais eficiente e aqui está como lidar

  private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)Keys.Enter)
        {
            e.Handled = true;
            button1.PerformClick();
        }
    }

e diga paz ao 'Ding'

Mawardy
fonte
2
Isso funcionou perfeitamente para mim. e.Handled aparentemente desativa o 'Ding'. Tornar o botão 'Enviar' (no meu caso) o padrão, não teria funcionado para mim porque eu queria manipular a tecla 'Enter' de maneira diferente para outras caixas de texto no formulário. <br/> <br/> A propósito, : Para este projeto eu estou usando o VB. assim, em vez de lançar e.KeyChar, eu convertê-lo: se e.KeyChar = ChrW (Keys.Enter Então ....
Mark Ainsworth
1
Dentro do KeyDown, usando e.Handlede e.SuppressKeyPressnão funcionou para mim - ainda tocando. Mas alterá-lo conforme sugerido aqui para usar o KeyPress' event and e.Handled` fez isso muito bem.
Jinlye
Esta deve ser a resposta correta, obrigado
Firas Shrourou 10/07
7

Use SuppressKeyPresspara interromper o processamento contínuo do pressionamento de tecla após manipulá-lo.

public class EntryForm: Form
{
   public EntryForm()
   {
   }

   private void EntryTextBox_KeyDown(object sender, KeyEventArgs e)
   {
      if(e.KeyCode == Keys.Enter)
      {
         e.Handled = true;
         e.SuppressKeyPress = true;
         // do some stuff

      }
      else if(e.KeyCode == Keys.Escape)
      {
          e.Handled = true;
          e.SuppressKeyPress = true;
          // do some stuff

      }
   }

   private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
   {
      if(e.KeyCode == Keys.Enter)
      {
         // do some stuff

      }
      else if(e.KeyCode == Keys.Escape)
      {
         // do some stuff

      }
   }
}
Snehasish
fonte
2

Eu tropecei neste post enquanto tentava lidar com um KeyDown que funcionou para mim.

If e.KeyCode = Keys.Enter Then
   e.SuppressKeyPress = True
   btnLogIn.PerformClick()
End If

Suprimir a pressão da tecla impede que o evento seja enviado ao controle subjacente. Isso deve funcionar se você estiver manipulando manualmente tudo o que a tecla Enter fará dentro dessa caixa de texto. Desculpe pelo Visual Basic.

Colin
fonte
2

Há muito pouca chance de alguém chegar a essa resposta, mas algumas outras respostas são realmente assustadoras. Suprimir evento KeyDownmata 2 eventos adicionais em um ataque. Definir e.Handledpropriedade como trueé inútil neste contexto.
A melhor maneira é definir a Form.AcceptButtonpropriedade para o botão de pesquisa real.
Há também outra maneira de utilizar a Enterchave - algumas pessoas podem querer que ela atue como TABbotão. Para fazer isso, adicione um novo Button, defina sua Locationpropriedade fora da Formárea (ie (-100, -100)) - definindo a Visiblepropriedade para falsedesativar os Buttonmanipuladores em alguns casos. Defina a Form.AcceptButtonpropriedade para o seu novo botão. No Clickmanipulador de eventos, adicione o seguinte código
this.SelectNextControl(ActiveControl, true, true, true, true)

Agora, você pode querer transferir focussomente quando focus-lo em TextBoxvocê pode querer qualquer teste ActiveControltipo ou uso e.Supresspropriedade em manipuladores de eventos de controles não destinados a uso Entercomo TAB é isso. Você nem precisa capturare.KeyCode

ArtK
fonte
1
$("#txtSomething").keypress(function (e) {
        if (e.which == 13) {

            e.Handled = true; //This will prevent the "ding" sound

            //Write the rest of your code
        }
    });
Code.Town
fonte
É isso que estou procurando.
Sid
1

No WinForms, a tecla Enter causa um som Ding porque a propriedade AcceptButton do formulário não está especificada. Se você não precisar de um AcceptButton, o som ding poderá ser suprimido definindo o formulário KeyPreview como true e insira o seguinte evento KeyPress:

private void Form_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\r')
        e.Handled = true;
}

Não importa qual controle esteja ativo, não haverá mais som ao pressionar a tecla Enter. Como a ordem de processamento de eventos de teclas é KeyDown, KeyPress e KeyUp, a tecla Enter ainda funcionará nos eventos KeyDown dos controles.

Berry Jansen
fonte
0

Defina a propriedade IsDefault do botão Pesquisar como true. Isso o tornará um botão padrão e será clicado automaticamente quando a tecla Enter for pressionada.

Zruty
fonte
Dos documentos aos quais você vinculouTo specify the default button of a form, set the AcceptButton property of the form to the desired button.
mdm
Sim, eu investiguei isso eu mesmo. Parece que as duas abordagens são intercambiáveis. AcceptButtonparece mais elegante, mas estou acostumado a IsDefaultmim mesmo.
Zruty
0

Bem, eu vivi com esse problema por tempo suficiente e procurei aqui.

Depois de pensar nisso por um bom tempo e querer a maneira mais simples de corrigi-lo, criei a maneira mais fácil, mas não tão elegante, de corrigi-lo.

Aqui está o que eu fiz.

  1. Coloque 2 botões invisíveis "Ok" e "Cancelar" no formulário.
  2. Defina a propriedade AcceptButton e CancelButton no formulário para os botões invisíveis.
  3. Não foi adicionado nenhum código aos botões!

Isso resolveu todos os problemas secundários listados neste segmento, incluindo o ToolStripMenu. Minha maior reclamação foi o BindingNavigator, quando eu inseria um número de registro na posição atual para navegar e pressionava enter.

De acordo com a pergunta original em que o programador queria uma função de pesquisa quando o botão Enter foi pressionado, simplesmente coloquei o código de pesquisa no botão OK invisível!

Até agora, isso parece resolver todos os problemas, mas como todos sabemos com o Visual Studio, algo provavelmente surgirá.

A única outra maneira elegante possível em que eu poderia pensar seria escrever uma nova classe de manipulação de teclas, que é muito trabalhosa para a maioria dos meus projetos.

user2793447
fonte
0

Você pode definir a caixa de texto como várias linhas como true e, em seguida, pressionar a tecla Enter.

private void yourForm_Load(object sender, EventArgs e)
    {
        textBox1.Multiline = true;
    }

//then write your TextBox codes
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        // doSomething();
    }
}
Shedrack Ikwabe
fonte
0

Eu mudei as propriedades da caixa de texto para uma caixa de texto com várias linhas e funciona para mim.

Christian Fontaine
fonte
A resposta já foi declarada abaixo em 22 de fevereiro. Você tem que cuidar de [entrar] também;)
Guloseimas
-2
void RTextBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == Keys.Enter)
    {
        //do ...
        bool temp = Multiline;
        Multiline = true;
        e.Handled = true;
        Multiline = temp;
    }
}
mahdi
fonte
1
Esta é uma resposta redundante com apenas código, sem explicação. Além disso, todo o Multilinecódigo é completamente irrelevante.
Jonathon Reinhart