web-dev-qa-db-ja.com

上、下、左、右の矢印キーはKeyDownイベントをトリガーしません

私は、すべてのキー入力をウィンドウ自体で処理する必要があるアプリケーションを構築しています。

パネル以外のフォーカスを取得できる各コントロールに対してtabstopをfalseに設定します(ただし、効果があるかどうかはわかりません)。

KeyPreviewをtrueに設定し、このフォームでKeyDownイベントを処理しています。

私の問題は、矢印キーが反応しなくなることです。

  • 矢印キーのみを押した場合、keydownイベントは発生しません。

  • Control修飾子で矢印キーを押すと、keydownイベントが発生します。

矢印キーが突然発砲イベントを停止する理由をご存知ですか?

66
Martin Delille
    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;                
        }
    }
56
alpha

私はまったく同じ問題を抱えていました。 @Snarfblamが提供する答えを検討しました。ただし、MSDNのドキュメントを読む場合、ProcessCMDKeyメソッドは、アプリケーションのメニュー項目のキーイベントをオーバーライドすることを意図しています。

私は最近、非常に有望に見えるMicrosoftのこの記事を偶然見つけました: http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx 。 Microsoftによると、最善の方法はe.IsInputKey=true;矢印キーを検出した後のPreviewKeyDownイベント内。そうすると、KeyDownイベントが発生します。

これは私にとっては非常にうまく機能し、ProcessCMDKeyをオーバーライドするよりもハック的なものではありませんでした。

59
Rodolfo Neuber

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

Rodolfo Neuberの返信 を参照してください。


(私の元の答え):

コントロールクラスから派生し、ProcessCmdKeyメソッドをオーバーライドできます。マイクロソフトは、これらのキーが複数のコントロールに影響し、フォーカスを移動するため、KeyDownイベントからこれらのキーを省略することを選択しましたが、他の方法でこれらのキーにアプリを反応させることは非常に困難です。

16
snarf

WinFormsからWPFウィンドウを呼び出すときに、同様の問題が発生しました。

var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
    ElementHost.EnableModelessKeyboardInterop(wpfwindow);
    wpfwindow.Show();

ただし、ウィンドウをdialogとして表示すると、うまくいきました。

var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
    ElementHost.EnableModelessKeyboardInterop(wpfwindow);
    wpfwindow.ShowDialog();

お役に立てれば。

2
Janez Krnc

残念ながら、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イベントと組み合わせて使用​​すると、確実に目標を達成できると思います。

2
Maxim Zaslavsky
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);
}
0
google dev

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#の矢印キー

ヴェイン

0
vaynenick

最善の方法は、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;
    }
0
Marcus.D

私は同じ問題を抱えていて、選択した回答のコードをすでに使用していました。このリンクは私にとっての答えでした。他の人にも。

C#で矢印を使用してWinFormのナビゲーションを無効にする方法

0
4mla1fn