ある程度のシステムになると、基底フォームを作成して共通処理を実装し、個別は継承先のフォームで実装する。というケースが多くなると思います。
キーボードイベントの処理順がうまくいかないと技術者から聞かれ、過去の記憶を確認すべく、サンプル書いて確認しました。(サンプルコード(zip)は記事の一番下に置いてあります)
【結果】
OnKey****の場合、継承先から順番に処理される。(上書き用途)
Key****のイベントハンドラの場合、基底から処理される
なお、本検証結果は「一般的な実装方法を用いた場合」の結果であり、色々とコードで工夫をなさった場合にはこの限りではありません。例)On***系の実装でbase.On***を呼ばない。とか、基底のイベントハンドラを登録するタイミングを継承先で指定するなど、振る舞いを変える方法はあると思います。
【検証した方法】
1.以下3つのフォームを用意する
・基底フォーム (TestBaseForm)
・基底を継承したフォーム (InheritForm1)
・さらに継承したフォーム(InheritInheritForm2)
2.それぞれに、同じメソッド、イベントを実装
3.プログラムを実行して、順番を把握
【実装イメージ】
【テストコード】
/// 同じコードを継承先のフォームにも記載
public partial class TestBaseForm : Form
{
string _myFormName = "TestBaseForm"; // ここは実装するフォーム名にする
public TestBaseForm()
{
InitializeComponent();
this.KeyPreview = true;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form_KeyDown);
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form_KeyPress);
this.KeyUp += new KeyEventHandler(this.Form_KeyUp);
}
protected override void OnKeyDown(KeyEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
base.OnKeyDown(e);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
base.OnKeyPress(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
base.OnKeyUp(e);
}
private void Form_KeyDown(object sender, KeyEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
}
private void Form_KeyUp(object sender, KeyEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
}
private void Form_KeyPress(object sender, KeyPressEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
}
}
【実行ログ】
Log内容 |
Method |
基底 |
継承1 |
継承2 |
InheritInheritForm2:OnKeyDown |
OnKeyDown |
|
|
〇 |
InheritForm1:OnKeyDown |
OnKeyDown |
|
〇 |
|
TestBaseForm:OnKeyDown |
OnKeyDown |
〇 |
|
|
TestBaseForm:Form_KeyDown |
KeyDown |
〇 |
|
|
InheritForm1:Form_KeyDown |
KeyDown |
|
〇 |
|
InheritInheritForm2:Form_KeyDown |
KeyDown |
|
|
〇 |
InheritInheritForm2:OnKeyPress |
OnKeyPress |
|
|
〇 |
InheritForm1:OnKeyPress |
OnKeyPress |
|
〇 |
|
TestBaseForm:OnKeyPress |
OnKeyPress |
〇 |
|
|
TestBaseForm:Form_KeyPress |
KeyPress |
〇 |
|
|
InheritForm1:Form_KeyPress |
KeyPress |
|
〇 |
|
InheritInheritForm2:Form_KeyPress |
KeyPress |
|
|
〇 |
InheritInheritForm2:OnKeyUp |
OnKeyUp |
|
|
〇 |
InheritForm1:OnKeyUp |
OnKeyUp |
|
〇 |
|
TestBaseForm:OnKeyUp |
OnKeyUp |
〇 |
|
|
TestBaseForm:Form_KeyUp |
KeyUp |
〇 |
|
|
InheritForm1:Form_KeyUp |
KeyUp |
|
〇 |
|
InheritInheritForm2:Form_KeyUp |
KeyUp |
|
|
〇 |
【まとめ】