Les flèches Haut, Bas, Gauche et droite ne déclenchent pas L'événement KeyDown
je construis une application où toutes les entrées de clés doivent être gérées par les fenêtres elles-mêmes.
j'ai mis tabstop à false pour chaque sorcière de contrôle pourrait saisir la mise au point sauf un panneau (mais je ne sais pas si elle a un effet).
j'ai mis la valeur true de KeyPreview et je gère L'événement de KeyDown sur ce formulaire.
mon problème est que parfois la touche Flèche ne répondent plus:
-
l'événement keydown n'est pas déclenché lorsque j'ai appuyé seulement sur une touche Flèche.
-
l'événement keydown est déclenché si j'appuie sur une touche Flèche avec le modificateur de contrôle.
avez-vous une idée de la raison pour laquelle ma touche fléchée a soudainement cessé de tirer?
9 réponses
protected override bool IsInputKey(Keys keyData)
{
switch (keyData)
{
case Keys.Right:
case Keys.Left:
case Keys.Up:
case Keys.Down:
return true;
case Keys.Shift | Keys.Right:
case Keys.Shift | Keys.Left:
case Keys.Shift | Keys.Up:
case Keys.Shift | Keys.Down:
return true;
}
return base.IsInputKey(keyData);
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
switch (e.KeyCode)
{
case Keys.Left:
case Keys.Right:
case Keys.Up:
case Keys.Down:
if (e.Shift)
{
}
else
{
}
break;
}
}
j'avais exactement le même problème. J'ai considéré la réponse @Snarfblam fournie; cependant, si vous lisez la documentation sur MSDN, la méthode ProcessCMDKey est destinée à outrepasser les événements clés pour les éléments de menu dans une application.
je suis tombé récemment sur cet article de microsoft, qui semble très prometteur: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx . Selon microsoft, le meilleur la chose à faire est de définir e.IsInputKey=true;
dans l'événement PreviewKeyDown
après avoir détecté les touches fléchées. Cela déclenchera l'événement KeyDown
.
cela a très bien fonctionné pour moi et a été moins hack-ish que d'écraser le ProcessCMDKey.
j'utilise PreviewKeyDown
private void _calendar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e){
switch (e.KeyCode){
case Keys.Down:
case Keys.Right:
//action
break;
case Keys.Up:
case Keys.Left:
//action
break;
}
}
Voir Rodolfo Neuber de la réponse de pour la meilleure réponse
(ma réponse originale):
dérivent d'une classe de contrôle et vous pouvez outrepasser la méthode ProcessCmdKey. Microsoft a choisi d'omettre ces clés des évènements KeyDown parce qu'elles affectent plusieurs contrôles et déplacent la mise au point, mais cela rend très difficile de faire réagir une application à ces clés d'une autre manière.
malheureusement, il est assez difficile d'accomplir cela avec les touches fléchées, en raison des restrictions dans les événements KeyDown. Cependant, il y a quelques façons de contourner cela:
- comme @Snarfblam l'a déclaré, Vous pouvez outrepasser la méthode ProcessCmdKey , qui conserve la capacité de parser les presses à touches fléchées.
- comme la réponse acceptée de cette question indique, XNA a une méthode intégrée appelé clavier.GetState () , qui vous permet d'utiliser des entrées de touches fléchées. Cependant, WinForms n'a pas cela, mais il peut être fait à travers un p/invoquer , ou par en utilisant une classe qui aide avec elle .
je recommande d'essayer d'utiliser cette classe. C'est assez simple de le faire:
var left = KeyboardInfo.GetKeyState(Keys.Left);
var right = KeyboardInfo.GetKeyState(Keys.Right);
var up = KeyboardInfo.GetKeyState(Keys.Up);
var down = KeyboardInfo.GetKeyState(Keys.Down);
if (left.IsPressed)
{
//do something...
}
//etc...
Si vous l'utilisez en combinaison avec l'événement KeyDown, je pensez que vous pouvez accomplir votre but de façon fiable.
j'ai eu un problème similaire lorsque j'ai appelé la fenêtre WPF de WinForms.
var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
ElementHost.EnableModelessKeyboardInterop(wpfwindow);
wpfwindow.Show();
Cependant, en montrant la fenêtre comme un dialogue , il a fonctionné
var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
ElementHost.EnableModelessKeyboardInterop(wpfwindow);
wpfwindow.ShowDialog();
Espérons que cette aide.
pour capturer les touches dans un contrôle de formes, vous devez dériver une nouvelle classe qui est basée sur la classe du contrôle que vous voulez, et vous surchargez le ProcessCmdKey().
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
//handle your keys here
}
exemple:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
//capture up arrow key
if (keyData == Keys.Up )
{
MessageBox.Show("You pressed Up arrow key");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
source complète... flèches dans C#
Vayne
la meilleure façon de faire, je pense, est de le gérer comme le MSDN a dit sur http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx
mais manipulez-le, comme vous en avez vraiment besoin. Mon chemin (dans l'exemple ci-dessous) est d'attraper tous les KeyDown ;-)
/// <summary>
/// onPreviewKeyDown
/// </summary>
/// <param name="e"></param>
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
{
e.IsInputKey = true;
}
/// <summary>
/// onKeyDown
/// </summary>
/// <param name="e"></param>
protected override void OnKeyDown(KeyEventArgs e)
{
Input.SetFlag(e.KeyCode);
e.Handled = true;
}
/// <summary>
/// onKeyUp
/// </summary>
/// <param name="e"></param>
protected override void OnKeyUp(KeyEventArgs e)
{
Input.RemoveFlag(e.KeyCode);
e.Handled = true;
}
j'ai eu le même problème et j'utilisais déjà le code dans la réponse choisie. ce lien a été la réponse pour moi; peut-être pour d'autres aussi.
comment désactiver la navigation sur WinForm avec les flèches en C#?