5.2 キーボード入力
5.2.1 キー入力に反応する
マウス入力と同様に、UIElement を継承する任意の描画要素はキーボードからの入力を受けることができます。
キーボードはマウスカーソルのようなものが存在しないため、キーを押したときにどの要素が入力対象になるのかはフォーカスで決定されます。キー入力を受けることができる要素は、キー入力のフォーカスを受けることができ、現在フォーカスを保有しているコントロールがキーの入力対象となります。通常、フォーカスを持つコントロールは、もっていない状態と視覚的に区別することができます。
こうした性質から、キーボードイベントはコントロールが受けるものであり、Shape をルートとする図形オブジェクトはフォーカスを取得しないためキー入力を受けません。
ユーザーが、任意のキーボード上のキーを押したとき、UIElement は KeyDown イベントを発生させます。また、キーを離したときは KeyUp イベントが発生します。
public event KeyEventHandler KeyDown
public event KeyEventHandler KeyUp
これらのイベントには、System.Windows.Input.KeyEventHandler デリゲートのオブジェクトを追加します。
public delegate void KeyEventHandler ( Object sender, KeyEventArgs e )
KeyEventHandler が受けるイベントオブジェクトは、入力されたキーに関する情報を提供する System.Windows.Input.KeyEventArgs クラスのオブジェクトです。
System.Object System.EventArgs System.Windows.RoutedEventArgs System.Windows.Input.InputEventArgs System.Windows.Input.KeyboardEventArgs System.Windows.Input.KeyEventArgs
public class KeyEventArgs : KeyboardEventArgs
KeyEventArgs クラスが提供するキーに関連する情報については後述するとして、この場では、まずキー入力に単純に反応するプログラムを作ってみましょう。
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Input; class Test : Window { [STAThread] public static void Main() { Window wnd = new Test(); Application app = new Application(); app.Run(wnd); } private Ellipse ellipse; public Test() { ellipse = new Ellipse(); ellipse.Fill = Brushes.Red; ellipse.Width = 100; ellipse.Height = 100; Content = ellipse; KeyDown += thisKeyDown; KeyUp += thisKeyUp; } private void thisKeyDown(object sender, KeyEventArgs e) { ellipse.Fill = Brushes.Blue; } private void thisKeyUp(object sender, KeyEventArgs e) { ellipse.Fill = Brushes.Red; } }
コード1は、キーボードの何らかのキーを押すと、ウィンドウの中央に赤い楕円形が青色に変化するというプログラムです。キーを離すと、楕円形は元の赤色に戻ります。この仕組みは、KeyDown イベントで Ellipse オブジェクトの Fill プロパティに青いブラシを設定し、KeyUp イベントで赤いブラシを設定することで実現しています。
5.2.2 入力されたキーを調べる
キー入力イベントが発生したとき、イベントハンドラはパラメータから取得した KeyEventArgs オブジェクトから入力されたキーの情報を得ることができます。イベントが、どのキーが押された発生したものなのかは Key プロパティから取得することができます。
public Key Key { get; }
Key プロパティが返す値は System.Windows.Input.Key 列挙体のいずれかです。
[TypeConverterAttribute(typeof(KeyConverter))] public Key
この列挙体には、キーボードに配列されている個々のキーを表すメンバが定義されています。そのため、非常に多くのメンバを保有していますが、メンバ名の多くは単純なアルファベットです。例えば「A」キーに対応する Key 列挙体のメンバは A メンバです。文字キーに対応するメンバは、その文字キーのアルファベットと同一の名前になっています。
その他のキーについては、ドキュメントを調べるしかありませんが、メンバ名はそのキーの一般的な名前に一致します。スペースキーであれば Space メンバ、Enter キーは Return メンバ、Backspace キーは Back メンバとなります。
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; class Test : Window { [STAThread] public static void Main() { Window wnd = new Test(); Application app = new Application(); app.Run(wnd); } private TextBlock textBlock; public Test() { textBlock = new TextBlock(); textBlock.FontSize = 40; textBlock.Text = "入力してください"; Content = textBlock; KeyUp += thisKeyUp; } private void thisKeyUp(object sender, KeyEventArgs e) { textBlock.Text = "入力キー: " + e.Key.ToString(); } }
コード2は、KeyUp イベントが発生すると、そのイベントの発生原因となったキーを TextBlock 上に表示するというプログラムです。この作業は非常に単純で、KeyEventArgs オブジェクトの Key プロパティが返す Key 列挙体の値を文字列化すれば、Key 列挙体のメンバ名を取得することができます。プログラムでは、その文字列を TextBlock に表示させているだけです。