テンプレート コントロールの開発
ASP.NET には、テンプレートと呼ばれる用途の広い機能があり、これによってコントロールのデータをコントロール自体の表示とは分離できます。テンプレート コントロール自体はユーザー インターフェイス (UI) を提供しません。コントロールの UI は、ページ開発者がインライン テンプレートを使用して提供します。インライン テンプレートを使用すると、コントロールの UI をカスタマイズできます。ASP.NET のテンプレートの詳細については、「ASP.NET クイック スタート」の「.NET サンプル - ASP.NET コントロールの作成」で「Template1 サンプル」の例を参照してください。
テンプレート コントロールを開発するには
System.Web.UI.INamingContainer インターフェイスを実装します。このインターフェイスは、メソッドのないマーカー インターフェイスです。これにより、コントロールの下に名前付けスコープが作成されるため、名前付けツリーの子コントロールにそれぞれ一意の識別子が付けらるようになります。
public class TemplatedFirstControl : Control,INamingContainer {...}
ParseChildrenAttribute をコントロールに適用し、引数として true を渡します。これにより、ASP.NET ページでコントロールが宣言によって使用されるときのテンプレート プロパティ タグの解析方法をページ パーサーに示します。テンプレート プロパティの定義方法については、手順 3 で説明します。
メモ WebControl から派生したコントロールの場合、WebControl が既に ParseChildrenAttribute でマークされているため、この属性を適用する必要はありません。
[ ParseChildren(ChildrenAsProperties = true)] public class TemplatedFirstControl : Control, INamingContainer {...}
ParseChildrenAttribute の詳細については、「ParseChildrenAttribute の使用方法」を参照してください。
System.Web.UI.ITemplate 型のプロパティを 1 つ以上定義します。ITemplate には、ページにインラインで組み込まれているテンプレートを使用してコントロールを作成する InstantiateIn メソッドがあります。InstantiateIn メソッドは、ASP.NET ページ フレームワークによって実装されるため、実装する必要はありません。ITemplate プロパティには、インスタンス化されたテンプレートを保持する INamingContainer コントロールを示す、System.Web.UI.TemplateContainerAttribute 型のメタデータ属性が必要です。この属性については、手順 4 で説明します。テンプレート プロパティを定義するコードを次に示します。
[TemplateContainer(typeof(FirstTemplateContainer))] public ITemplate FirstTemplate {...}
TemplateContainerAttribute の引数は、その内部でテンプレートをインスタンス化するコンテナ コントロールの型です。このコンテナ コントロールは、作成するテンプレート コントロールには依存しません。論理コンテナを使用する理由は、テンプレート コントロールが、さまざまなデータを使用して繰り返しインスタンス化する必要のあるテンプレートを持つことが多いためです。ルート テンプレート コントロールと異なるコンテナ コントロールを使用すると、このような複数のインスタンスを作成できます。論理コンテナは、テンプレート内の子コントロールに対する直接の INamingContainer です。この関係の詳細については、「template 宣言のあるデータ連結コントロールの開発」を参照してください。
メモ コンテナ コントロールの子コントロールにページ上で一意の名前を付ける必要があるため、このコンテナ コントロール自体が INamingContainer を実装する必要があります。
public class FirstTemplateContainer : Control, INamingContainer {...}
テンプレートに子コントロールを作成するために、CreateChildControls メソッドをオーバーライドします。オーバーライドするには、次の手順に従います。
- テンプレート コンテナをインスタンス化します。
- テンプレート プロパティの InstantiateIn メソッドを呼び出して、テンプレート コンテナを引数として渡します。ITemplate インターフェイスで宣言されている InstantiateIn メソッドが、テンプレートの要素をテンプレート コンテナの子コントロールとしてインスタンス化します。InstantiateIn メソッドは、ASP.NET ページ フレームワークによって実装されるため、実装する必要はありません。
- テンプレート コントロールの Controls コレクションに、テンプレート コンテナのインスタンスを追加します。
CreateChildControls の実装を次のコード片に示します。
private Control myTemplateContainer; protected override void CreateChildControls () { if (FirstTemplate != null) { myTemplateContainer = new FirstTemplateContainer(this); FirstTemplate.InstantiateIn(myTemplateContainer); Controls.Add(myTemplateContainer); } else { Controls.Add(new LiteralControl(Text + " " + DateTime)); } }
Control から継承した OnDataBinding メソッドをオーバーライドして、EnsureChildControls メソッドを呼び出します。これにより、ページ フレームワークがテンプレート内のデータ連結式を評価する前に、必ずテンプレートの子コントロールが作成されます。登録されているイベント ハンドラを確実に呼び出せるように、基本クラスの OnDataBinding メソッドを呼び出す必要もあります。
protected override void OnDataBinding(EventArgs e) { EnsureChildControls(); base.OnDataBinding(e); }
手順 5 で、CreateChildControls メソッド内のロジックを繰り返し実行し、コントロールの各テンプレート プロパティに対してテンプレートをインスタンス化します。
テンプレート コントロール、テンプレートの関連コンテナ コントロール、およびこのコントロールを使用するページの例については、「テンプレート コントロールのサンプル」を参照してください。