フォームには、いくつかのボタンを備えたパネルがあります。button1 がクリックされると、パネルをラベル (例: ) を持つ新しい UserControl に置き換えthis.Controls.Clear()
ますthis.Controls.Add(UserControl1)
。私のuserControlのラベルを除いて、KeyDownハンドラーがあります。正常に動作し、イベントが発生しますが、キー Up、Down、Left、Right では発生しません。これらのキーに違いがある理由を誰か説明できますか? イベントが発生するかどうかを決定するものは何ですか?
4 に答える
2 つの基本的な理由。最初の不可解な問題: Label コントロールはフォーカスを受け取ることができないため、キーストロークを確認できません。その KeyDown イベントがデザイナーで非表示になっている理由。キーストロークがまったく表示されない理由がよくわかりません。より一般的な理由は、カーソルと TAB キーがナビゲーションに使用され、あるコントロールから別のコントロールにフォーカスを移動することです。これは、キーがコントロールに渡される前に行われます。IsInputKey() メソッドをオーバーライドできるように、コントロールをオーバーライドする必要があります。しかし、より実際には、代わりに UserControl の ProcessCmdKey() をオーバーライドして、両方の問題を解決します。
また、プログラムに厄介なハンドル リークがあることにも注意してください。 削除するコントロールで Dispose() メソッドを呼び出さずに Controls.Clear() を呼び出さないでください。後で再利用するつもりでない限り、あまり一般的ではありません。これは厄介な種類のリークであり、ガベージ コレクターが解決せず、最初にプログラムを遅く扱いにくくした後、最終的にプログラムをクラッシュさせます。
MSDNによると:
このイベントは.NETFrameworkインフラストラクチャをサポートしており、コードから直接使用することを目的としたものではありません。
ラベルにフォーカスがあるときにユーザーがキーを押したときに発生します。
編集:これに代わるイベントはないようです。私が読んだことから、矢印キーは間違いなく検出されるはずです。コードを入力してください。
代わりに、メソッド ProcessCmdKey をオーバーライドする必要があります。矢印キーは、他の標準キーと同じようには処理されません。別の解決策は、Microsoft が提案したhttp://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspxです。
矢印キーを処理するには、フォームの KeyPreview プロパティを true に設定し、特定のコントロール レベルではなくフォーム レベルで処理します。私はそうしました、そしてそれは完璧に機能します!
上記がうまくいかない場合は、次のProcessCmdKey
ようなことを検討してください。
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
{
if(KeyData == Keys.Right)
{
//Move Right
return true;
}
else
{
return base.ProcessCmdKey(msg, keyData);
}
}