2010-03-22 13 views
6

cuando presionamos una tecla y seguimos presionándola, el evento de pulsación de tecla y tecla desaparece continuamente. ¿Hay alguna manera de permitir que estos disparos solo después de un ciclo completo, por ejemplo, tecla y luego clave.¿cómo no se permiten múltiples keystokes recibidos con presionar una tecla?

Me gustaría que el usuario no pueda presionar la tecla de forma continuada en lugar de desear que el usuario tenga que presionar y luego soltar el teclado para escribir un carácter.

para que el siguiente caso no ocurra, por ejemplo: pppppppppppppppppppppppp cuando el usuario presiona 'p' durante 1 seg.

Respuesta

7

Declarar un booleano isKeyDown, en el evento KeyDown, establezca el booleano en verdadero. En el evento KeyUp, establezca el valor booleano en falso.

Esto es código de ejemplo

bool isKeyDown=false; 
public void control_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) 
{ 
    if(isKeyDown) 
     return; 
    isKeyDown=true; 
    // do what you want to do 
} 

public void control1_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e) 
{ 
    isKeyDown=false; 
    // do you key up event, if any. 
} 
+0

Como decía el cartel, ambos eventos se disparan (keyDown seguido de keyUp) incluso cuando es una clave que se repite – Ian

+0

@iAn: eso no es cierto. obtiene keydowns repetidos, pero solo una tecla. –

+0

@iAn: MSDN dice lo contrario: "El evento KeyDown ocurre cuando el usuario presiona cualquier tecla. El evento KeyUp ocurre cuando el usuario suelta la clave. Los eventos Duplicar KeyDown ocurren cada vez que la tecla se repite, si la tecla se mantiene presionada, pero solo un evento KeyUp se genera cuando el usuario suelta la clave ". – Niki

2

Para evitar una llave de disparar-varias veces cuando se mantiene presionada: debe utilizar la propiedad SuppressKeyPress así:

bool isKeyRepeating = false; 

public void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) 
{ 
    if (isKeyRepeating) 
    { 
     e.SuppressKeyPress = true; 
    } 
    else 
    { 
     isKeyRepeating = true; 
    } 

} 

public void textBox1_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e) 
{ 
    isKeyRepeating = false; 
} 

Ver: KeyEventArgs..::.Handled Property ... y ... KeyEventArgs..::.SuppressKeyPress Property .... para información relevante

+0

Suena bien. –

+0

Si configura 'KeyPreview to' como verdadero y utiliza el mismo código (arriba) en los controladores KeyDown y KeyUp del formulario: todos los cuadros de texto en ese formulario tendrán suprimida la repetición de tecla. No lo he probado en otros controles aparte de los TextBoxes. El hecho de que Nobugz (que es más inteligente que yo) dio una respuesta a continuación sugiere que este código, incluso en un nivel de Forma, no evitaría la repetición de tecla en alguna otra condición de la que no tenga conocimiento. – BillW

5

Puede hacerlo a nivel de toda la aplicación al filtrar los mensajes de tecla con IMess filtro de edad. Aquí hay un ejemplo:

public partial class Form1 : Form, IMessageFilter { 
    public Form1() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
     this.FormClosed += (s, e) => Application.RemoveMessageFilter(this); 
    } 

    private Keys mLastKey = Keys.None; 

    public bool PreFilterMessage(ref Message m) { 
     if (m.Msg == 0x100 || m.Msg == 0x104) { 
     // Detect WM_KEYDOWN, WM_SYSKEYDOWN 
     Keys key = (Keys)m.WParam.ToInt32(); 
     if (key != Keys.Control && key != Keys.Shift && key != Keys.Alt) { 
      if (key == mLastKey) return true; 
      mLastKey = key; 
     } 
     } 
     else if (m.Msg == 0x101 || m.Msg == 0x105) { 
     // Detect WM_UP, WM_SYSKEYUP 
     Keys key = (Keys)m.WParam.ToInt32(); 
     if (key == mLastKey) mLastKey = Keys.None; 
     } 
     return false; 
    } 
    } 

Una cosa que persiguió es el recuento de repeticiones en el mensaje WM_KEYDOWN. Curiosamente, esto no funcionó en mi máquina, era 1 para repetir las llaves. No estoy seguro por qué.

+0

@nobugz +1 ¡Siempre aprendo mucho de tus respuestas! Algo muy interesante sucedió anteriormente con la eliminación de MessageFilter en el formulario cerrado. Supongo que vas "tan profundo" en tu respuesta para cubrir todos los casos posibles de entrada de control. Supongo que no hay forma de manejar esto en toda la Aplicación que sea independiente de cualquier Forma (s)? – BillW

+0

@BillW: ¡Gracias! Esto es para toda la aplicación, IMessageFilter opera para todas las formas. Si solo funcionara de una forma, esta no es la solución correcta. Supongo que es un tipo de aplicación de juegos, así que debería estar bien. –

+0

Por supuesto, ahora puedo ver su aplicación amplia y me pregunto cómo me perdí de ver eso para empezar :) – BillW

Cuestiones relacionadas