25


5

私は小さなゲームを作成しています、ゲームは窓の形のパネルに印刷されます。 キーダウンイベントをキャプチャして矢印キーが押されたかどうかを確認したいのですが、問題はキャプチャできないようです。

私が説明してみましょう、私は4つのボタンと他のさまざまなコントロールを持っています、そして例えばユーザーがボタンの1つを押すと。

私は何かを試した

private void KeyDown(KeyEventArgs e){if(e.KeyCode == Keys.Left){game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.E); game.DrawObjects(panel1.CreateGraphics());そうでなければ(e.KeyCode == Keys.Right){game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.W); game.DrawObjects(panel1.CreateGraphics());そうでなければ(e.KeyCode == Keys.Up){game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.N); game.DrawObjects(panel1.CreateGraphics());そうでなければ(e.KeyCode == Keys.Down){game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.S); game.DrawObjects(panel1.CreateGraphics()); }}

そしてフォームキーダウンイベントが押されたとき、私はこれを使いました

private void MainForm_KeyDown(オブジェクト送信側、KeyEventArgs e){KeyDown(e); }

私はまた、windowsフォーム上のボタンや他のさまざまなコントロールのためのkeydownを追加しました、しかし私は何の反応も得られていません。 呼び出されているかどうかを確認するために関数内にブレークポイントを設定しましたが、そのブレークポイントがトリガすることはありませんか。

何か案は?

最も最適な方法は、(現在どのコントロールにフォーカスがあるかにかかわらず)トリガーしてKeyDownメソッドを呼び出す一般的なKeyDownイベントを持つことです。

4 Answer


29


フォームの KeyPreviewプロパティを` true`に設定しましたか? これにより、フォームは主要なイベントを「一見する」ようになります。

更新: Button`にフォーカスがあるときにこれを適切に動作させるのは少しトリッキーです。 Buttonコントロールは、矢印キーの押下を傍受して、タブ順で次または前のコントロールにフォーカスを移動し、 `KeyDown、` KeyUp`および `KeyPress`イベントが発生しないようにします。 しかし、 `PreviewKeyDown`イベントが発生するので、それを使うことができます。

プライベート無効Form_KeyDown(オブジェクトセンダ、KeyEventArgs e){e.Handled = ProcessKeyDown(e.KeyCode); }

// event handler for the PreViewKeyDown event for the buttons
プライベートvoid

}

private bool ProcessKeyDown(Keys keyCode){switch(keyCode){case Keys.Up:{//上向きに動作するアクションはtrueを返します。 } Keys.Down:{//下向き矢印に作用するとtrueが返されます。 } Keys.Left:{//左向き矢印のアクションはtrueを返します。 } Keys.Right:{//右矢印のアクションはtrueを返します。 falseを返します。 }

それでも、焦点はかなり醜い方法で動き回る…​


17


'' '' '

  • IsInputKey *の動作をオーバーライドする

'' '' '

  • IsInputKey ビヘイビアをオーバーライドして、右矢印キーを特別なビヘイビアキーとしてではなくInputKeyとして扱うことを通知する必要があります。 そのためには、各コントロールのメソッドをオーバーライドする必要があります。 私はあなたにあなたの獲得したボタンを作成するように忠告します、 MyButton *を言おう

以下のクラスは、右矢印キーが特別なキーとして扱われないように* IsInputKey *メソッドをオーバーライドするカスタムButtonを作成します。 そこから他の矢印キーや他のものに簡単に作ることができます。

MyButton:Button {protected override bool IsInputKey(Keys keyData){if(keyData == Keys.Right){trueを返します。 } else {return base.IsInputKey(keyData);} }}}

'' '' '

その後は、keyDownイベントイベントをそれぞれ異なるButtonまたはフォーム自体で処理できます。

ボタンのKeyDownメソッドで、これらのプロパティを設定してみます。

プライベート無効myButton1_KeyDown(オブジェクトセンダ、KeyEventArgs e){e.Handled = true; // DoSomething(); }
  • または -

次の形式で一般的な動作を処理します。(_e.Handled = true; _をボタンに設定しないでください)

private void Form1_KeyDown(オブジェクト送信側、KeyEventArgs e){// DoSomething(); }


17


この問題を解決する最も簡単な方法は、フォームのProcessCmdKey()メソッドをオーバーライドすることです。 このように、キー操作時にどのコントロールにフォーカスがあるかに関係なく、キー処理ロジックは実行されます。 それに加えて、フォーカスされたコントロールが処理後にキーを取得する(falseを返す)か、しない(trueを返す)かを選択することもできます。 あなたの小さなゲームの例はこのように書き直すことができます:

保護オーバーライドbool ProcessCmdKey(Refメッセージmsg、Keys keyData){if(keyData == Keys.Left){MoveLeft();} DrawGame();何でも(); trueを返します。 //キーコントロールを表示するアクティブコントロールの場合はfalseを返し、それ以外の場合は(keyData == Keys.Right){MoveRight();}を返します。 DrawGame();何でも(); trueを返します。 //キー操作を確認するアクティブコントロールの場合はfalseを返し、そうでない場合は(keyData == Keys.Up){MoveUp(); DrawGame();何でも(); trueを返します。 //キーコントロールを表示するアクティブコントロールの場合はfalseを返し、そうでない場合は(keyData == Keys.Down){MoveDown(); DrawGame();何でも(); trueを返します。 //アクティブなコントロールがキー押下を確認するにはfalseを返し、そうでない場合はbase.ProcessCmdKey(ref msg、keyData);を返します。 }


7


パブリック部分クラスForm1:フォーム{public Form1(){InitializeComponent();} KeyPreview = true; KeyDown = new KeyEventHandler(Form1_KeyDown); }

void Form1_KeyDown(オブジェクト送信側、KeyEventArgs e){System.Diagnostics.Debug.Write(e.KeyCode); }}