2010-03-22 1 views
6

Wenn wir eine Taste drücken und die Taste gedrückt halten, wird das Tastendruck- und Tastenereignis kontinuierlich ausgelöst. Gibt es eine Möglichkeit, diese nur nach einem kompletten Zyklus, z. B. Keydown, zu zünden und dann hochzuschalten.Wie kann man mehrere Keystokes, die mit einem Tastendruck empfangen werden, nicht zulassen?

Ich möchte der Benutzer nicht in der Lage sein, die Taste kontinuierlich zu drücken lieber würde der Benutzer müssen dann drücken Sie die Tastatur, um ein Zeichen eingeben!

so dass folgende Fälle nicht auftreten: zB pppppppppppppppppppppppppp, wenn der Benutzer 'p' für 1 Sekunde drückt.

Antwort

7

Deklarieren Sie eine boolesche isKeyDown, in der KeyDown Event, setzen Sie den Booleschen Wert auf True. Setzen Sie im Ereignis KeyUp den Booleschen Wert auf false.

Dies ist ein Beispielcode

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

Wie das Poster sagte, feuern beide Ereignisse (keyDown gefolgt von keyUp), selbst wenn es ein Schlüssel ist, der sich wiederholt: – Ian

+0

@iAn: Das stimmt nicht. Sie erhalten wiederholte Keydowns, aber nur eine Tastenkombination. –

+0

@iAn: MSDN sagt anders: "Das KeyDown-Ereignis tritt auf, wenn der Benutzer eine beliebige Taste drückt. Das KeyUp-Ereignis tritt auf, wenn der Benutzer den Schlüssel freigibt. Doppelte KeyDown-Ereignisse treten jedes Mal auf, wenn der Schlüssel wiederholt wird, wenn der Schlüssel nur gedrückt wird Ein KeyUp-Ereignis wird generiert, wenn der Benutzer den Schlüssel freigibt. " – Niki

2

Um einen Schlüssel aus dem Brennen mehrmals zu verhindern, wenn gedrückt gehalten wird: Sie SuppressKeyPress Eigenschaft wie so verwenden müssen:

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; 
} 

See: KeyEventArgs..::.Handled Property ... und ... KeyEventArgs..::.SuppressKeyPress Property .... für relevante Informationen

+0

Hört sich gut an. –

+0

Wenn Sie die KeyPreview eines Formulars auf "true" setzen und denselben Code (oben) in den KeyDown- und KeyUp-Handlern des Formulars verwenden: Bei allen TextBoxen auf diesem Formular wird die Schlüsselwiederholung unterdrückt. Ich habe es nicht auf anderen Steuerelementen als TextBoxen getestet. Die Tatsache, dass Nobugz (wer ist verdammt schlauer als ich) unten eine Antwort gab, deutet darauf hin, dass dieser Code selbst auf einer Formularebene die Schlüsselwiederholung in einer anderen Bedingung, die mir nicht bekannt ist, nicht verhindern würde. – BillW

5

Sie können es Anwendung-weit tun, indem Sie die Schlüssel-Down-Nachrichten mit IMess filtern alterFilter. Hier ein Beispiel:

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; 
    } 
    } 

Eine Sache, die ich verfolgen die Wiederholungszahl in der WM_KEYDOWN Nachricht. Seltsamerweise funktionierte das nicht auf meiner Maschine, es war 1 für Tastenwiederholung. Nicht sicher warum.

+0

@nobugz +1 Ich lerne immer viel aus deinen Antworten! Sehr interessante Sachen, die oben mit dem Entfernen des MessageFilters auf geschlossenem Formular gehen. Ich nehme an, dass Sie in Ihrer Antwort "so tief" gehen, um jeden möglichen Fall von Steuereingaben zu erfassen? Ich nehme an, dass es keine Möglichkeit gibt, dies auf einer anwendungsweiten Basis zu handhaben, die unabhängig von Formularen ist? – BillW

+0

@BillW: Danke! Dies ist anwendungsweit, IMessageFilter funktioniert für alle Formulare. Wenn es nur für eine Form funktionieren sollte, ist dies nicht die richtige Lösung. Ich nehme an, das ist eine Art Gaming-App, also sollte es in Ordnung sein. –

+0

Natürlich kann ich jetzt sehen, es ist Anwendung breit und frage mich, wie ich es vermisste zu sehen, dass mit zu beginnen :) – BillW

Verwandte Themen