Top > .NET & Control > 独自Form(フォーム)継承の意味 

独自Form(フォーム)継承の意味

(「Formクラスを継承したクラス(画面)」を継承する)
(「Formクラスから派生したクラス(画面)」から派生する)

よく考えてみたら、画面はFormクラスを継承して作成するので、普段からカスタムコントロールを作っているようなものなんだけど、その画面を使用するという発想がなかった。

「Formクラスを継承した画面」を継承して別の画面を作る

Visual Studio 2003/2003では、どうもデザイン時におかしな動作をしたらしいが、VS 2008ではデザインも実行も問題なく動作している。

本格的な使用は行っていないため、保証は出来ないが試す価値はありそうだ。

例えば

ヘッダ、フッタ部のあるベース画面を作っておき、ベース画面(A)を継承して画面(B)を複数作成することが出来る。

共通のレイアウトと機能を持つ「複数の画面」を作成する場合にメリットがある。


ベース画面(A)

プロパティを以下のように設定した。

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;

次に、Form1 を 継承して Form2 を作成する。


画面(B)

Form1でデザインされた内容、プロパティ値が、Form2 にそのまま引き継がれているがわかる。
ヘッダ部およびフッタ部は、Form2のデザインコードには含まれていないため、 アイコンでそのことを示している。デザインとして見えているだけで、編集することは出来ない。 

感想

これまで、この発想が生まれなかったこと、人からも聞いたことがなかったことを考えると、この方法には、それほどメリットを感じられない。しかし、1画面1プログラムで作る場合、シングル・ウィンドウを複数表示させて使用する場合には、一考の価値あり。

UIデザインの領域になるが、「こういうことができる」ということを知っていると、応用範囲やよりベストなUI構築に役立つだろう。 

注意点

ベース画面(A)と画面(B)で「同じイベント」の処理を行う際は、十分注意して設計する必要がある。

例えば、

ベース画面(A Form1)を起動する。画面をクリックすると画面(B Form2)を表示する。
画面(B Form2)は、画面をクリックすると自分を閉じる。

という、同じイベントを作成した。

ベース画面(A)

private void Form1_Click(object sender, EventArgs e)
{
	Form2 form = new Form2();

	form.Location = this.Location;
	form.Show();
}						

画面(B)

private void Form2_Click(object sender, EventArgs e)
{
	this.Close();
}

期待する動作にならなかった。ベース画面(A)をクリックすると、画面(B)を表示する。画面(B)をクリックすると閉じてベース画面(A)が現れる。というシナリオを想定。

実際にテストをしてみると、画面(B)でクリックすると、まず ベース画面(A)の Form1_Click() が実行され、その後画面(B)の Form2_Click()が実行される。

Controlクラスの OnClick の処理は、以下の様になっている。

protected virtual void OnClick(EventArgs e)
{
	EventHandler handler = (EventHandler)base.Events[EventClick];
	if (handler != null)
	{
		handler(this, e);
	}
}

ControlクラスからFormクラスまでの間に OnClick はオーバーライドされていないため、Controlクラスの OnClick が実行される。

つまり、Form2のオブジェクトで、Form1、Form2 それぞれのイベントハンドラが登録されることが原因と判明。

this.Click += new System.EventHandler(this.Form1_Click);
this.Click += new System.EventHandler(this.Form2_Click);

したがって、この2つのイベントハンドラは、OnClickが実行されると、Form1_Click Form2_Click の順に実行する。つじつまは合っている。

このケースの対策としては、

Form2 側は、イベントハンドラではなくて、OnClick() をオーバーライドして、ベース(Form1)を実行しないようにすればいい。

protected override void OnClick(EventArgs e)
{
//base.OnClick(e);
this.Close();
}						

なお、このサンプル例は、画面がちらつくため、実用に耐えられないからやらない方がいい。

▲ページトップに戻る