チュートリアル : Visual C# による複合コントロールの作成
更新 : 2007 年 11 月
複合コントロールは、カスタム グラフィカル インターフェイスの作成と再利用のための手段を提供します。複合コントロールは、基本的には表示できる形式を持つコンポーネントです。そのため、ユーザー コントロールは、1 つ以上の Windows フォーム コントロール、コンポーネント、またはコードのブロックから構成でき、ユーザー入力を検査したり、表示プロパティを変更したり、作成者によって要求されるその他のタスクを実行したりすることで機能を拡張できます。複合コントロールは、他のコントロールと同じ方法で Windows フォームに配置できます。このチュートリアルの前半では、ctlClock という名前の単純な複合コントロールを作成します。後半では、継承によって ctlClock の機能を拡張します。
メモ : |
---|
使用している設定またはエディションによっては、表示されるダイアログ ボックスやメニュー コマンドがヘルプに記載されている内容と異なる場合があります。設定を変更するには、[ツール] メニューの [設定のインポートとエクスポート] をクリックします。詳細については、「Visual Studio の設定」を参照してください。 |
プロジェクトの作成
新しいプロジェクトを作成するときには、その名前を指定することにより、ルート名前空間、アセンブリ名、およびプロジェクト名を設定し、既定のコンポーネントが正しい名前空間に含まれるようにします。
ctlClockLib コントロール ライブラリおよび ctlClock コントロールを作成するには
[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックして [新しいプロジェクト] ダイアログ ボックスを開きます。
Visual C# プロジェクトの一覧の [Windows コントロール ライブラリ] プロジェクト テンプレートをクリックし、[プロジェクト名] ボックスに「ctlClockLib」と入力して、[OK] をクリックします。
プロジェクト名 ctlClockLib は、既定でルート名前空間にも割り当てられます。ルート名前空間は、アセンブリ内のコンポーネント名の修飾に使用されます。たとえば、ctlClock という名前のコンポーネントが 2 つのアセンブリに含まれる場合は、ctlClockLib.ctlClock. という形で目的の ctlClock コンポーネントを指定できます。
ソリューション エクスプローラで、UserControl1.cs を右クリックし、[名前の変更] をクリックします。ファイル名を「ctlClock.cs」に変更します。コード要素 "UserControl1" へのすべての参照の名前を変更するかどうかを確認するダイアログ ボックスが表示されたら、[はい] をクリックします。
メモ : 既定では、複合コントロールはシステムによって提供される UserControl クラスを継承します。UserControl クラスは、すべての複合コントロールに必要な機能を提供し、標準のメソッドおよびプロパティを実装します。
[ファイル] メニューの [すべてを保存] をクリックして、プロジェクトを保存します。
複合コントロールへの Windows コントロールおよびコンポーネントの追加
ビジュアル インターフェイスは、複合コントロールの基本的な部分です。このビジュアル インターフェイスは、デザイナ画面に 1 つ以上の Windows コントロールを追加することによって実装されます。次の例では、複合コントロールに Windows コントロールを取り込んで、機能を実装するコードを記述します。
複合コントロールに Label と Timer を追加するには
ソリューション エクスプローラで ctlClock.cs を右クリックし、[デザイナの表示] をクリックします。
ツールボックスの [コモン コントロール] ノードを展開し、[Label] をダブルクリックします。
label1 という名前の Label がデザイナ画面のコントロールに追加されます。
デザイナで、[label1] をクリックします。[プロパティ] ウィンドウで、次のプロパティを設定します。
プロパティ
変更後の値
Name
lblDisplay
Text
(空白)
TextAlign
MiddleCenter
Font.Size
14
ツールボックスの [コンポーネント] ノードを展開し、[Timer] をダブルクリックします。
Timer はコンポーネントであるため、実行時には表示できる形式を持ちません。このため、デザイナ画面にはコントロールと共には表示されず、コンポーネント デザイナ (デザイナ画面の下部にあるトレイ) に表示されます。
コンポーネント デザイナで、[Timer1] をクリックし、Interval プロパティを 1000、Enabled プロパティを true に設定します。
Interval プロパティは、Timer コンポーネントが時を刻む頻度を制御します。timer1 が時を刻むたびに、timer1_Tick イベントのコードが実行されます。このプロパティは、タイマが何ミリ秒ごとに時を刻むかを表しています。
コンポーネント デザイナで、[Timer1] をダブルクリックして、ctlClock の timer1_Tick イベントに移動します。
コードを次のコード サンプルのように変更します。アクセス修飾子を必ず private から protected に変更してください。
[C#]
protected void timer1_Tick(object sender, System.EventArgs e) { // Causes the label to display the current time. lblDisplay.Text = DateTime.Now.ToLongTimeString(); }
このコードは、現在の時刻を lblDisplay に表示します。timer1 の間隔は 1000 に設定されているため、このイベントは 1000 ミリ秒ごとに発生します。したがって、現在の時刻は 1 秒ごとに更新されます。
virtual キーワードを使用して、メソッドをオーバーライドできるように変更します。詳細については、後の「ユーザー コントロールからの継承」を参照してください。
protected virtual void timer1_Tick(object sender, System.EventArgs e)
[ファイル] メニューの [すべてを保存] をクリックして、プロジェクトを保存します。
複合コントロールへのプロパティの追加
現在、クロック コントロールは、それぞれが固有のプロパティ セットを持つ Label コントロールと Timer コンポーネントをカプセル化しています。各コントロールのプロパティは、コントロールの後続のユーザーからはアクセスできませんが、適切なコード ブロックを作成することによってカスタム プロパティを作成および公開できます。次の手順では、ユーザーが背景とテキストの色を変更できるようにするプロパティをコントロールに追加します。
複合コントロールにプロパティを追加するには
ソリューション エクスプローラで、ctlClock.cs を右クリックし、[コードの表示] をクリックします。
コントロールのコード エディタが表示されます。
public partial class ctlClock ステートメントを探します。左中かっこ ({) の下に次のコードを入力します。
[C#]
private Color colFColor; private Color colBColor;
これらのステートメントは、作成するプロパティの値を格納するために使用するプライベート変数を作成します。
手順 2. の変数宣言の下に次のコードを入力します。
[C#]
// Declares the name and type of the property. public Color ClockBackColor { // Retrieves the value of the private variable colBColor. get { return colBColor; } // Stores the selected value in the private variable colBColor, and // updates the background color of the label control lblDisplay. set { colBColor = value; lblDisplay.BackColor = colBColor; } } // Provides a similar set of instructions for the foreground color. public Color ClockForeColor { get { return colFColor; } set { colFColor = value; lblDisplay.ForeColor = colFColor; } }
上記のコードは、このコントロールを今後使用するユーザーが ClockForeColor および ClockBackColor という 2 つのカスタム プロパティを使用できるようにします。get ステートメントと set ステートメントは、プロパティに適切な機能を実装するコードと共に、プロパティ値の格納と取得の機能を提供します。
[ファイル] メニューの [すべてを保存] をクリックして、プロジェクトを保存します。
コントロールのテスト
コントロールはスタンドアロン アプリケーションではないため、コンテナでホストする必要があります。コントロールの実行時の動作をテストし、ユーザー コントロール テスト コンテナでそのプロパティを実行します。詳細については、「方法 : UserControl の実行時の動作をテストする」を参照してください。
コントロールをテストするには
F5 キーを押してプロジェクトをビルドし、ユーザー コントロール テスト コンテナでコントロールを実行します。
テスト コンテナのプロパティ グリッドで、ClockBackColor プロパティを検索し、プロパティを選択してカラー パレットを表示します。
任意の色をクリックして選択します。
コントロールの背景色が、選択した色に変更されます。
同様なイベントのシーケンスを使用して、ClockForeColor プロパティが予想どおりに機能することを確認します。
このセクションと前のセクションでは、コンポーネントと Windows コントロールをコードと結合し、複合コントロールの形式にパッケージ化してカスタム機能を提供する方法を説明しました。複合コントロールのプロパティを公開し、完了後にコントロールをテストする方法を学びました。次のセクションでは、ctlClock をベースとして継承した複合コントロールを構築する方法を学びます。
複合コントロールからの継承
前のセクションでは、再利用可能な複合コントロールに Windows コントロール、コンポーネント、およびコードを組み込む方法を学びました。この複合コントロールをベースにして、他のコントロールを作成できます。基本クラスからクラスを派生するプロセスは継承と呼ばれます。このセクションでは、ctlAlarmClock という名前の複合コントロールを作成します。このコントロールは、親コントロールである ctlClock から派生します。ここでは、親のメソッドをオーバーライドし、新しいメソッドおよびプロパティを追加することにより、ctlClock の機能を拡張する方法を学びます。
継承コントロールの作成の最初の手順は、親コントロールからの派生です。これにより、親コントロールのプロパティ、メソッド、およびグラフィカル特性をすべて持つ新しいコントロールが作成されます。このコントロールに基づいて、新しい機能を追加したり機能を変更したりできます。
継承コントロールを作成するには
ソリューション エクスプローラで、[ctlClockLib] を右クリックします。[追加] をポイントし、[ユーザー コントロール] をクリックします。
[新しい項目の追加] ダイアログ ボックスが表示されます。
[継承されたユーザー コントロール] テンプレートを選択します。
[ファイル名] ボックスに「ctlAlarmClock.cs」と入力し、[追加] をクリックします。
[継承ピッカー] ダイアログ ボックスが表示されます。
[コンポーネント名] の [ctlClock] をダブルクリックします。
ソリューション エクスプローラで、現在のプロジェクトを最後まで参照します。
メモ : 現在のプロジェクトに ctlAlarmClock.cs という名前のファイルが追加されています。
アラーム プロパティの追加
複合コントロールにプロパティを追加する場合と同じ方法で、継承コントロールにプロパティを追加できます。ここでは、プロパティ宣言の構文を使用してコントロールに 2 つのプロパティを追加します。AlarmTime プロパティは、アラームを鳴らす日付と時刻の値を格納します。AlarmSet プロパティは、アラームが設定されているかどうかを示します。
複合コントロールにプロパティを追加するには
ソリューション エクスプローラで、[ctlAlarmClock] を右クリックし、[コードの表示] をクリックします。
public class ステートメントを探します。コントロールが ctlClockLib.ctlClock から継承される点に注意してください。左中かっこ ({) ステートメントの下に次のコードを入力します。
[C#]
private DateTime dteAlarmTime; private bool blnAlarmSet; // These properties will be declared as public to allow future // developers to access them. public DateTime AlarmTime { get { return dteAlarmTime; } set { dteAlarmTime = value; } } public bool AlarmSet { get { return blnAlarmSet; } set { blnAlarmSet = value; } }
コントロールのグラフィカル インターフェイスへの追加
継承したコントロールには、継承元のコントロールと同じビジュアル インターフェイスがあります。継承コントロールには親コントロールと同じ内在コントロールがありますが、内在コントロールのプロパティは特に公開されない限り使用できません。継承した複合コントロールのグラフィカル インターフェイスも、他の複合コントロールと同じように拡張できます。引き続き、アラーム クロックのビジュアル インターフェイスに、アラームが鳴ったときに点滅するラベル コントロールを追加します。
ラベル コントロールを追加するには
ソリューション エクスプローラで、[ctlAlarmClock] を右クリックし、[デザイナの表示] をクリックします。
ctlAlarmClock のデザイナがメイン ウィンドウに表示されます。
コントロールの表示部分をクリックし、[プロパティ] ウィンドウを表示します。
メモ : すべてのプロパティが表示されていますが、淡色表示になっています。つまり、これらのプロパティは lblDisplay に対してネイティブであり、[プロパティ] ウィンドウでは変更もアクセスもできません。既定では、複合コントロールに含まれているコントロールは private であり、どのような方法によってもプロパティにアクセスできません。
メモ : 複合コントロールを今後使用するユーザーがその内部のコントロールにアクセスできるようにするには、内部のコントロールを public または protected として宣言します。これにより、適切なコードを使用して、複合コントロールに含まれるコントロールのプロパティを設定したり変更したりできるようになります。
複合コントロールに Label コントロールを追加します。
マウスを使用して、Label コントロールを表示ボックスのすぐ下にドラッグします。[プロパティ] ウィンドウで、次のプロパティを設定します。
プロパティ
設定値
Name
lblAlarm
Text
Alarm!
TextAlign
MiddleCenter
Visible
false
アラーム機能の追加
前の手順では、複合コントロールでアラーム機能を有効にするためのプロパティおよびコントロールを追加しました。この手順では、現在の時刻とアラームの時刻を比較し、一致した場合は、アラームを点滅させるコードを追加します。ctlClock の timer1_Tick メソッドをオーバーライドしてコードを追加することにより、ctlClock の固有の機能をすべて保持しながら ctlAlarmClock の機能を拡張できます。
ctlClock の timer1_Tick メソッドをオーバーライドするには
コード エディタで、private bool blnAlarmSet; ステートメントを検索します。このステートメントの直後に、次のステートメントを追加します。
[C#]
private bool blnColorTicker;
コード エディタで、クラスの末尾にある右中かっこ (}) を検索します。中かっこの直前に、次のコードを追加します。
[C#]
protected override void timer1_Tick(object sender, System.EventArgs e) { // Calls the Timer1_Tick method of ctlClock. base.timer1_Tick(sender, e); // Checks to see if the alarm is set. if (AlarmSet == false) return; else // If the date, hour, and minute of the alarm time are the same as // the current time, flash an alarm. { if (AlarmTime.Date == DateTime.Now.Date && AlarmTime.Hour == DateTime.Now.Hour && AlarmTime.Minute == DateTime.Now.Minute) { // Sets lblAlarmVisible to true, and changes the background color based on // the value of blnColorTicker. The background color of the label // will flash once per tick of the clock. lblAlarm.Visible = true; if (blnColorTicker == false) { lblAlarm.BackColor = Color.Red; blnColorTicker = true; } else { lblAlarm.BackColor = Color.Blue; blnColorTicker = false; } } else { // Once the alarm has sounded for a minute, the label is made // invisible again. lblAlarm.Visible = false; } } }
このコードを追加することで、いくつかのタスクが実行されます。override ステートメントは、基本コントロールから継承されたメソッドの代わりに、このメソッドを使用するようにコントロールに指示します。このメソッドが呼び出されると、メソッドは base.timer1_Tick ステートメントを呼び出すことにより、オーバーライドするメソッドを呼び出します。その結果、元のコントロールに含まれるすべての機能がこのコントロールに継承されます。メソッドは次に追加のコードを実行してアラーム機能を組み込みます。アラームが発生すると、点滅するラベル コントロールが表示されます。
これで、アラーム付き時計はほぼ完成です。後は、アラームを止める手段を実装するだけです。これを行うには、lblAlarm_Click メソッドにコードを追加します。
アラームを止める手段を実装するには
ソリューション エクスプローラで、ctlAlarmClock.cs を右クリックし、[デザイナの表示] をクリックします。
デザイナが表示されます。
コントロールにボタンを追加します。ボタンのプロパティを次のように設定します。
プロパティ
値
Name
btnAlarmOff
Text
Disable Alarm
デザイナで、[btnAlarmOff] をダブルクリックします。
コード エディタが開き、private void btnAlarmOff_Click 行が表示されます。
このメソッドを次のコードのように変更します。
[C#]
private void btnAlarmOff_Click(object sender, System.EventArgs e) { // Turns off the alarm. AlarmSet = false; // Hides the flashing label. lblAlarm.Visible = false; }
[ファイル] メニューの [すべてを保存] をクリックして、プロジェクトを保存します。
フォームでの継承コントロールの使用
継承コントロールは、基本クラスである ctlClock のテストと同様の方法でテストできます。F5 キーを押してプロジェクトをビルドし、ユーザー コントロール テスト コンテナでコントロールを実行します。詳細については、「方法 : UserControl の実行時の動作をテストする」を参照してください。
コントロールを使用できるようにするには、フォーム上でコントロールをホストする必要があります。標準複合コントロールと同様に、継承複合コントロールはスタンドアロン型ではないため、フォームまたは他のコンテナでホストする必要があります。ctlAlarmClock は機能が拡張されているため、テストにも追加のコードが必要です。次の手順では、ctlAlarmClock の機能をテストするための簡単なプログラムを記述します。ctlAlarmClock の AlarmTime プロパティを設定および表示するコードを作成し、固有の機能をテストします。
コントロールをビルドしてテスト フォームに追加するには
ソリューション エクスプローラで、[ctlClockLib] を右クリックし、[ビルド] をクリックします。
ソリューションに新しい Windows アプリケーション プロジェクトを追加し、「Test」という名前を付けます。
ソリューション エクスプローラで、テスト プロジェクトの [参照設定] ノードを右クリックします。[参照の追加] をクリックして [参照の追加] ダイアログ ボックスを表示します。[プロジェクト] タブをクリックします。ctlClockLib プロジェクトが [プロジェクト名] の下に表示されます。プロジェクトをダブルクリックしてテスト プロジェクトへの参照を追加します。
ソリューション エクスプローラで、Test を右クリックし、[ビルド] をクリックします。
ツールボックスで、[ctlClockLib コンポーネント] ノードを展開します。
[ctlAlarmClock] をダブルクリックして、ctlAlarmClock をフォームにコピーします。
ツールボックスで、[DateTimePicker] を検索してダブルクリックし、DateTimePicker コントロールをフォームに追加します。また、[Label] をダブルクリックして Label コントロールを追加します。
マウスを使用して、フォーム上で各コントロールを使いやすい位置に移動します。
コントロールのプロパティを次のように設定します。
コントロール
プロパティ
値
label1
Text
(空白)
Name
lblTest
dateTimePicker1
Name
dtpTest
Format
デザイナで、[dtpTest] をダブルクリックします。
コード エディタが開き、private void dtpTest_ValueChanged が表示されます。
コードを次のように変更します。
[C#]
private void dtpTest_ValueChanged(object sender, System.EventArgs e) { ctlAlarmClock1.AlarmTime = dtpTest.Value; ctlAlarmClock1.AlarmSet = true; lblTest.Text = "Alarm Time is " + ctlAlarmClock1.AlarmTime.ToShortTimeString(); }
ソリューション エクスプローラで、Test を右クリックし、[スタートアップ プロジェクトに設定] をクリックします。
[デバッグ] メニューの [デバッグ開始] をクリックします。
テスト プログラムが起動します。ctlAlarmClock コントロールの現在時刻が更新され、DateTimePicker コントロールに開始時刻が表示されます。
DateTimePicker で分が表示されている部分をクリックします。
キーボードを使用して、ctlAlarmClock によって表示されている現在の時刻より 1 分後の値を設定します。
アラーム設定時刻は lblTest に表示されます。表示時刻がアラームの設定時刻になるまで待ちます。表示時刻がアラームの設定時刻になったときに、lblAlarm が点滅します。
btnAlarmOff をクリックしてアラームを止めます。その後で、アラームを再び設定できます。
このチュートリアルでは、多数の重要な概念を扱いました。複合コントロール コンテナにコントロールやコンポーネントを組み込んで複合コントロールを作成する方法を学びました。また、コントロールにプロパティを追加する方法や、カスタム機能を実装するコードを記述する方法も学びました。最後のセクションでは、継承によって特定の複合コントロールの機能を拡張し、オーバーライドによりホストのメソッドの機能を変更する方法を学びました。
参照
処理手順
方法 : [ツールボックスのカスタマイズ] ダイアログ ボックスにコントロールを表示する
チュートリアル : Visual C# による Windows フォーム コントロールからの継承