私は、すべてのキー入力をウィンドウ自体で処理する必要があるアプリケーションを構築しています。
パネル以外のフォーカスを取得できる各コントロールに対してtabstopをfalseに設定します(ただし、効果があるかどうかはわかりません)。
KeyPreviewをtrueに設定し、このフォームでKeyDownイベントを処理しています。
私の問題は、矢印キーが反応しなくなることです。
矢印キーのみを押した場合、keydownイベントは発生しません。
Control修飾子で矢印キーを押すと、keydownイベントが発生します。
矢印キーが突然発砲イベントを停止する理由をご存知ですか?
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;
}
}
私はまったく同じ問題を抱えていました。 @Snarfblamが提供する答えを検討しました。ただし、MSDNのドキュメントを読む場合、ProcessCMDKeyメソッドは、アプリケーションのメニュー項目のキーイベントをオーバーライドすることを意図しています。
私は最近、非常に有望に見えるMicrosoftのこの記事を偶然見つけました: http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx 。 Microsoftによると、最善の方法はe.IsInputKey=true;
矢印キーを検出した後のPreviewKeyDown
イベント内。そうすると、KeyDown
イベントが発生します。
これは私にとっては非常にうまく機能し、ProcessCMDKeyをオーバーライドするよりもハック的なものではありませんでした。
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;
}
}
Rodolfo Neuberの返信 を参照してください。
(私の元の答え):
コントロールクラスから派生し、ProcessCmdKeyメソッドをオーバーライドできます。マイクロソフトは、これらのキーが複数のコントロールに影響し、フォーカスを移動するため、KeyDownイベントからこれらのキーを省略することを選択しましたが、他の方法でこれらのキーにアプリを反応させることは非常に困難です。
WinFormsからWPFウィンドウを呼び出すときに、同様の問題が発生しました。
var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
ElementHost.EnableModelessKeyboardInterop(wpfwindow);
wpfwindow.Show();
ただし、ウィンドウをdialogとして表示すると、うまくいきました。
var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
ElementHost.EnableModelessKeyboardInterop(wpfwindow);
wpfwindow.ShowDialog();
お役に立てれば。
残念ながら、KeyDownイベントの制限により、矢印キーでこれを達成することは非常に困難です。ただし、これを回避する方法はいくつかあります。
そのクラスを使用することをお勧めします。そうするのは非常に簡単です:
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...
これをKeyDownイベントと組み合わせて使用すると、確実に目標を達成できると思います。
protected override bool IsInputKey(Keys keyData)
{
if (((keyData & Keys.Up) == Keys.Up)
|| ((keyData & Keys.Down) == Keys.Down)
|| ((keyData & Keys.Left) == Keys.Left)
|| ((keyData & Keys.Right) == Keys.Right))
return true;
else
return base.IsInputKey(keyData);
}
Formsコントロールでキーストロークをキャプチャするには、目的のコントロールのクラスに基づく新しいクラスを派生させ、ProcessCmdKey()をオーバーライドする必要があります。
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
//handle your keys here
}
例:
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);
}
完全なソース... C#の矢印キー
ヴェイン
最善の方法は、MSDNが http://msdn.Microsoft.com/en-us/library/system.windows.forms.controlで述べたように処理することだと思います.previewkeydown.aspx
しかし、それを処理する、あなたが本当にそれを必要とする方法。私の方法(以下の例では)は、すべての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;
}
私は同じ問題を抱えていて、選択した回答のコードをすでに使用していました。このリンクは私にとっての答えでした。他の人にも。