Detén el 'Ding' al presionar Enter

124

Tengo una aplicación de formularios Windows Forms muy simple. Y, en Windows (o, al menos, en las aplicaciones de Windows Forms), cuando presiona Intro mientras está dentro de un control TextBox de una sola línea, escucha un Ding. Es un sonido desagradable, que indica que no puede ingresar una nueva línea, porque es un TextBox de una sola línea.

Todo esto está bien. Sin embargo, en mi formulario, tengo 1 TextBox y un botón de búsqueda. Y estoy permitiendo que el usuario realice una búsqueda presionando Enter después de que haya terminado de escribir, para que no tenga que usar el mouse para hacer clic en el botón Buscar.

Pero se produce este sonido Ding. Es muy molesto.

¿Cómo podemos hacer que el sonido no se reproduzca en absoluto en mi formulario?

@David H - Así es como estoy detectando la presión de entrar:

private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        // Perform search now.
    }
}
bendr
fuente
¿Cómo detecta que se ha presionado Enter cuando el foco está en el cuadro de texto?
David Heffernan
En el Panel de propiedades, haga doble clic en el evento KeyDown o KeyUp. Luego, en la Vista de código, escribe el código que estoy a punto de poner en mi pregunta para yah.
bendr
2
KeyPress es probablemente el evento correcto y desea establecer e.Handled = true
David Heffernan
Gracias, @David, no sabía esto :)
bendr
7
Desearía que hubiera alguna forma de suprimir el molesto ding pero permitir que la presión de la tecla burbujee. A veces, presionar una tecla es solo presionar una tecla, sin necesidad de alarma.
flipdoubt

Respuestas:

56

Consulte la propiedad Form.AcceptButton . Puede usarlo para especificar un botón predeterminado para un formulario, en este caso para presionar Intro.

De los documentos:

Esta propiedad le permite designar una acción predeterminada para que ocurra cuando el usuario presione la tecla ENTER en su aplicación. El botón asignado a esta propiedad debe ser un IButtonControl que esté en el formulario actual o ubicado dentro de un contenedor en el formulario actual.

También hay una propiedad CancelButton para cuando el usuario presiona escape.

mdm
fuente
1
Gracias @mdm, esto funcionó mejor para mí. :) Volveré a votar cuando tenga más reputación.
bendr
1
@bendr tengo el mismo problema ... pero estoy usando UserControl ... no tiene Form.AcceptButton ... ¿cómo solucionarlo?
Murhaf Sousli
1
Visual Studio no parece tener un campo en el panel Propiedades para esto. Tiene que hacerse en código, aparentemente. this.AcceptButton = buttonOK; this.CancelButton = buttonCancel;
Chris
5
Esto no funcionará para ToolStripButtons o si desea usar la tecla ENTRAR para validar un TextBox o ToolStripTextBox. El mejor enfoque sería la respuesta de Lucio Fonseca, que funcionó para mí con ToolStripTextBox.
Robert S.
No veo tu solución no tienes un ejercicio práctico para estar más iluminado
Pedro Ávila
198

Esto funciona para mi:

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;

     }

 }

SuppressKeyPress es el verdadero truco. Espero que eso te ayude.

Lucio Fonseca
fuente
30
Esta es la única respuesta válida, en mi opinión. e.Handled = true;fue insuficiente; fue el SuppressKeyPressque hizo el truco.
Jonathon Reinhart
12
textBox1_KeyUp ding en esta situación independientemente de Handled o SuppressKeyPress
stackuser83
4
Funciona para mí con ToolStripTextBox.KeyDown. Ninguna otra solución lo hizo. ¡Gracias!
Robert S.
1
No funcionó para mí en mi evento textboxyKeyDown
Alex Jolig
7
Esta debería ser la respuesta aceptada. La respuesta aceptada actual requiere un botón estándar colocado en el formulario que es desagradable.
Javid
56

Tratar

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 fuego
fuente
Correcto, pero solo funcionará si el foco todavía está en el TextBox. ¿Qué pasa si el usuario presiona Tabprimero?
mdm
4
@mdm Depende del diseño de la interfaz de usuario. Quizás OP solo quiera esta acción cuando el foco está en el cuadro de texto. Eso es bastante común.
David Heffernan
2
Si el usuario presionó Tab, el foco ya no estará en el TextBox, el siguiente Contorl que será Focused es el Control de Botón, que no emite ese sonido cuando presiona Enter en él. :-)
bendr
@David, gracias por tu ejemplo. Solo lo probé. Y cada vez que pongo e.Handled = true en el evento .KeyPress, no se ejecuta ningún otro código. Lo único que sucede es que todo el texto en el cuadro de texto se selecciona (y ni siquiera tengo un código que seleccione ningún texto)
bendr
1
La respuesta de Lucio Fonseca fue la única que encontré para solucionar el problema.
Jonathon Reinhart
15

Simplemente agregue e.SuppressKeyPress = true;su declaración "si".

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
fuente
13

Puede usar KeyPress en lugar de KeyUp o KeyDown, es más eficiente y aquí se explica cómo manejar

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

y dile paz al 'Ding'

Mawardy
fuente
2
Esto funcionó perfectamente para mí. e.Handled aparentemente desactiva el 'Ding'. Hacer que el botón 'Enviar' (en mi caso) sea el predeterminado, no me habría funcionado porque quería manejar la tecla 'Enter' de manera diferente para otros cuadros de texto en el formulario. <br/> <br/> Por cierto : Para este proyecto estoy usando VB. así que en lugar de enviar e.KeyChar, lo convierto: if e.KeyChar = ChrW (Keys.Enter Then ....
Mark Ainsworth
1
Dentro de KeyDown, usando e.Handledy e.SuppressKeyPressno funcionó para mí, todavía sonando. Pero cambiarlo como se sugiere aquí para usar KeyPress' event and e.Handled` lo hizo bien.
Jinlye
Esta debería ser la respuesta correcta, gracias
Firas Shrourou
7

Úselo SuppressKeyPresspara detener el procesamiento continuo de la pulsación de tecla después de manipularla.

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
fuente
2

Me encontré con esta publicación mientras intentaba manejar un KeyDown, esto funcionó para mí.

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

Al suprimir la pulsación de tecla, el evento no se envía al control subyacente. Esto debería funcionar si está manejando manualmente todo lo que hará la tecla Intro dentro de ese cuadro de texto. Lo siento por Visual Basic.

Colin
fuente
2

Hay muy pocas posibilidades de que alguien obtenga esta respuesta, pero algunas otras respuestas son realmente aterradoras. Supresión de eventos al KeyDownmatar 2 eventos adicionales en un solo golpe. Establecer la e.Handledpropiedad en truees inútil en este contexto.
La mejor manera es establecer la Form.AcceptButtonpropiedad en el botón de búsqueda real.
También hay otra forma de utilizar la Entertecla: algunas personas pueden querer que actúe como TABbotón. Para hacer eso, agregue un nuevo Button, establezca su Locationpropiedad fuera del Formárea (es decir (-100, -100)); establecer la Visiblepropiedad en falsepuede deshabilitar los Buttoncontroladores en algunos casos. Establezca la Form.AcceptButtonpropiedad en su nuevo botón. En el Clickcontrolador de eventos, agregue el siguiente código
this.SelectNextControl(ActiveControl, true, true, true, true)

Ahora, es posible que desee transferir focussolo cuando focussea TextBoxposible que desee probar el ActiveControltipo o usar la e.Supresspropiedad en los controladores de eventos de los controles que no deben usarse Entercomo TAB Eso es todo. Ni siquiera necesitas capturare.KeyCode

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

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

            //Write the rest of your code
        }
    });
Código.Town
fuente
Esto es lo que busco.
Sid
1

En WinForms, la tecla Enter produce un sonido Ding porque no se especifica la propiedad de formulario AcceptButton. Si no necesita un AcceptButton, el sonido ding se puede suprimir configurando el formulario KeyPreview en verdadero e ingrese el siguiente evento KeyPress:

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

No importa qué control esté activo, no habrá más sonido ding al presionar la tecla Enter. Dado que el orden de procesamiento de eventos clave es KeyDown, KeyPress y KeyUp, la tecla Enter seguirá funcionando para los eventos KeyDown de los controles.

Berry Jansen
fuente
0

Establezca la propiedad IsDefault de su botón de búsqueda en true. Esto lo convertirá en un botón predeterminado y se hará clic automáticamente cuando se presione Enter.

Zruty
fuente
De los documentos a los que vinculóTo specify the default button of a form, set the AcceptButton property of the form to the desired button.
MDM
Sí, lo he investigado yo mismo. Parece que ambos enfoques son intercambiables. AcceptButtonparece más elegante, pero estoy acostumbrado a IsDefaultmí mismo.
Zruty
0

Bueno, viví con este problema el tiempo suficiente y lo busqué aquí.

Después de pensar en esto durante bastante tiempo y de querer la forma más sencilla de solucionarlo, se me ocurrió la forma más sencilla pero no tan elegante de solucionarlo.

Aquí esta lo que hice.

  1. Pon 2 botones invisibles "Aceptar" y "Cancelar" en el formulario.
  2. Establezca la propiedad AcceptButton y CancelButton en el formulario en los botones invisibles.
  3. ¡No se agregó ningún código a los botones!

Esto resolvió todos los problemas secundarios enumerados en este hilo, incluido ToolStripMenu. Mi mayor queja fue el BindingNavigator, cuando ingresaba un número de registro en la posición actual para navegar y presionaba enter.

De acuerdo con la pregunta original en la que el programador quería una función de búsqueda cuando se presionó el botón Enter, simplemente puse el código de búsqueda en el botón OK invisible.

Hasta ahora, esto parece resolver todos los problemas, pero como todos sabemos con Visual Studio, es probable que surja algo.

La única otra forma elegante posible en la que podría pensar sería escribir una nueva clase de manejo de pulsaciones de teclas, que es mucho trabajo para la mayoría de mis proyectos.

usuario2793447
fuente
0

Puede configurar su cuadro de texto multilínea en verdadero y luego presionar la tecla Intro.

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
fuente
0

Cambié las propiedades del cuadro de texto para un cuadro de texto de varias líneas y funciona para mí.

Christian Fontaine
fuente
La respuesta ya se indicó a continuación el 22 de febrero. Tienes que encargarte de [entrar] también;)
Goodies
-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
fuente
1
Esta es una respuesta redundante con solo código, sin explicación. Además, todo el Multilinecódigo es completamente irrelevante.
Jonathon Reinhart