単一のフォームを持つ Windows フォーム アプリ (.net/c# を使用) があります。フォームには、デザイン ビューから配置されたコントロールがありません。
ユーザーコントロールクラスから継承し、フォームにぴったり合うようにサイズ設定されたカスタム「スクリーン」クラスもあります。スクリーン クラスには、追加先のフォームにコールバックできる多数のイベント ハンドラがあります。
プログラムで作成され、コントロールとしてフォームに追加される Screen オブジェクトの配列があります。
foreach(Screen s in screens)
{
Controls.Add(s);
}
いずれかの画面で次または前のボタンをクリックすると、(イベント ハンドラーを介して) フォーム内の適切なメソッドが間接的に呼び出されます。フォームは、Visible プロパティと Enabled プロパティを介して画面の切り替えを処理します。つまり、画面を削除する必要がある場合や、適切な Visible プロパティと Enabled プロパティがそれぞれ false と true に設定されていることを示しています。
各画面は、表示内容を制御するコードを担当します。フォーム コードは、ある画面から別の画面への流れを処理するだけです。
したがって、メイン フォームの次のボタン ハンドラーの例は次のようになります。
screens[currScreen].Visible = false;
screens[currScreen].Enabled = false;
currScreen++;
screens[currScreen].Visible = true;
screens[currScreen].Enabled = true;
エスケープキーを処理しようとするまで、これはすべてうまく機能します。
ユーザーがエスケープキーを押してアプリを終了できるようにしたい。したがって、最初に考えたのは、プログラムで初期化するときに、各画面に次のコードを単純に追加することでした...
screen[n].KeyUp += OnKeyUP; // Where on key up is an event handler in the main form
ここでのアイデアは、コントロールでイベントをキャプチャし、呼び出すフォームで処理できるということでした...
private void OnKeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Escape)
{
this.Close();
}
}
このタイプのイベント キャプチャは、特定のマウス操作の場合に既に使用しているように機能しますが、キーボードでは機能しません。そのため、イベントハンドラーを画面クラスに入れてみましたが、これも機能しませんでした。
おそらくコントロールにフォーカスがないため、キーボードをキャプチャしていないことに気付きました。そこで、フォームに次のデバッグ コードを追加しました...
Console.WriteLine("Control: {0} - Focus = {1}", this.ToString(), this.Focused);
foreach (Control c in this.Controls)
{
Console.WriteLine("Control: {0} - Focus = {1}", c.ToString(), c.Focused);
}
そして、何もフォーカスがないので、何がフォーカスを持っているのかわかりませんか?
また、フォーカスを取得するものを取得できないようです。コントロールとフォームで .Activate() と .Focus() を呼び出してみましたが、上記のコードを再実行するたびにまだ何もフォーカスされていません。
画面コントロールをフォームに追加するコードを削除してから、キーストロークの上のコードを実行すると、フォームの KeyUp イベントによって検出され、フォームにフォーカスがあります。コントロールを追加すると、フォーカスを持つものが停止するようです。
キーアップイベントを受け取るか、フォーカスを与えるためにスクリーンコントロールを取得する方法を知っている人はいますか? 私が間違っているのは本当に明らかに愚かなことだと確信していますが、今私は壁に頭をぶつけています。
ありがとう。