WisdomSoft - for your serial experiences.

5.2 キーボード入力

キー入力を感知し、押されたキーに応じて反応するプログラムを作成します。フォーカスを受ける UIElement オブジェクトは、キー入力を感知すると KeyDawn イベントと KeyUp イベントを発生させます。

5.2.1 キー入力に反応する

マウス入力と同様に、UIElement を継承する任意の描画要素はキーボードからの入力を受けることができます。

キーボードはマウスカーソルのようなものが存在しないため、キーを押したときにどの要素が入力対象になるのかはフォーカスで決定されます。キー入力を受けることができる要素は、キー入力のフォーカスを受けることができ、現在フォーカスを保有しているコントロールがキーの入力対象となります。通常、フォーカスを持つコントロールは、もっていない状態と視覚的に区別することができます。

こうした性質から、キーボードイベントはコントロールが受けるものであり、Shape をルートとする図形オブジェクトはフォーカスを取得しないためキー入力を受けません。

ユーザーが、任意のキーボード上のキーを押したとき、UIElement は KeyDown イベントを発生させます。また、キーを離したときは KeyUp イベントが発生します。

UIElement クラス KeyDown イベント
public event KeyEventHandler KeyDown
UIElement クラス KeyUp イベント
public event KeyEventHandler KeyUp

これらのイベントには、System.Windows.Input.KeyEventHandler デリゲートのオブジェクトを追加します。

System.Windows.Input.KeyEventHandler デリゲート
public delegate void KeyEventHandler (
    Object sender, KeyEventArgs e
)

KeyEventHandler が受けるイベントオブジェクトは、入力されたキーに関する情報を提供する System.Windows.Input.KeyEventArgs クラスのオブジェクトです。

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 クラスが提供するキーに関連する情報については後述するとして、この場では、まずキー入力に単純に反応するプログラムを作ってみましょう。

コード1
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 実行結果

コード1は、キーボードの何らかのキーを押すと、ウィンドウの中央に赤い楕円形が青色に変化するというプログラムです。キーを離すと、楕円形は元の赤色に戻ります。この仕組みは、KeyDown イベントで Ellipse オブジェクトの Fill プロパティに青いブラシを設定し、KeyUp イベントで赤いブラシを設定することで実現しています。

5.2.2 入力されたキーを調べる

キー入力イベントが発生したとき、イベントハンドラはパラメータから取得した KeyEventArgs オブジェクトから入力されたキーの情報を得ることができます。イベントが、どのキーが押された発生したものなのかは Key プロパティから取得することができます。

KeyEventArgs クラス Key プロパティ
public Key Key { get; }

Key プロパティが返す値は System.Windows.Input.Key 列挙体のいずれかです。

System.Windows.Input.Key 列挙体
[TypeConverterAttribute(typeof(KeyConverter))] 
public Key

この列挙体には、キーボードに配列されている個々のキーを表すメンバが定義されています。そのため、非常に多くのメンバを保有していますが、メンバ名の多くは単純なアルファベットです。例えば「A」キーに対応する Key 列挙体のメンバは A メンバです。文字キーに対応するメンバは、その文字キーのアルファベットと同一の名前になっています。

その他のキーについては、ドキュメントを調べるしかありませんが、メンバ名はそのキーの一般的な名前に一致します。スペースキーであれば Space メンバ、Enter キーは Return メンバ、Backspace キーは Back メンバとなります。

コード2
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 実行結果

コード2は、KeyUp イベントが発生すると、そのイベントの発生原因となったキーを TextBlock 上に表示するというプログラムです。この作業は非常に単純で、KeyEventArgs オブジェクトの Key プロパティが返す Key 列挙体の値を文字列化すれば、Key 列挙体のメンバ名を取得することができます。プログラムでは、その文字列を TextBlock に表示させているだけです。