スタイルによって、コントロールの外観を制御します。スタイルをサポートするコントロールを開発する場合は、Font、Height、Width などの厳密に型指定されたプロパティを公開し、スタイル プロパティと連携するためのメソッドを提供する System.Web.UI.WebControls.WebControl から派生させます。ASP.NET コントロールにおけるスタイルの概要については、「ASP.NET クイック スタート」の「.NET サンプル - ASP.NET でのスタイルのカスタマイズ」で「Style9 サンプル」を参照してください。
WebControl クラスは、スタイルをサポートするために次に示す 2 つの手法を提供します。
- System.Web.UI.WebControl.Style 型または System.Web.UI.WebControl.Style から派生した型の厳密に型指定されたスタイル プロパティを公開します。
- WebControl.Style コレクションに名前/値のペアを追加することによって HTML 属性としてスタイルを出力します。コントロールを開発する場合は、この手法を使用しないでください。この手法は、厳密に型指定されたプロパティとしてコントロールが公開しないスタイルをユーザー側で追加できるように提供されています。スタイルの設定 (「ASP.NET クイック スタート」の「.NET サンプル - ASP.NET でのスタイルのカスタマイズ」) で示されているように、コントロールのユーザーは、この方法により、プログラムと宣言の両方によってスタイルを設定できます。
厳密に型指定されたスタイル プロパティの公開
WebControl から派生するサーバー コントロールである Web サーバー コントロールは、コントロールの型指定されたスタイル全体を決定する WebControl.ControlStyle プロパティを継承します。ControlStyle の型は、次のリストで説明するように、スタイル関連の機能をカプセル化するクラスである Style です。
Style は、Font、Height、Width、ForeColor、BackColor などのカスケード スタイル シートのスタイルに対応するプロパティを備えています。WebControl は、ControlStyle プロパティのサブプロパティにデリゲートすることによって、これらのスタイル プロパティを最上位レベルのプロパティとして公開します。
Style は、スタイルを属性として HtmlTextWriter オブジェクトにレンダリングするための Style.AddAttributesToRender メソッドを公開します。これによって WebControl は、スタイルのレンダリングを ControlStyle プロパティにデリゲートできます。
メモ WebControl の Render メソッドをオーバーライドする場合は、WebControl が提供する基本レンダリング機能が保持されていることを確認する必要があります。たとえば、HtmlTextWriter インスタンスの Write メソッドを直接呼び出すために Render メソッドをオーバーライドすると、WebControl にビルドされているスタイル レンダリング機能を失います。Render をオーバーライドするときに推奨される手法の例については、「サーバー コントロールのレンダリングのサンプル」を参照してください。
Style は、スタイルのコピー (Style.CopyFrom) とマージ (Style.MergeWith) のためのメソッドを提供します。これらのメソッドを使用する例については、「template 宣言のあるデータ連結コントロールのサンプル」を参照してください。
Style は、状態管理機能を提供する IStateManager インターフェイスを実装します。この結果、コントロールは状態管理をスタイル プロパティにデリゲートできます。IStateManager コントラクトの一部として、Style は LoadViewState、SaveViewState、TrackViewState などのメソッドを実装します。Style は StateBag 型を引数とするオーバーロードされたコンストラクタも備えています。WebControl は、ViewState を Style コンストラクタに渡すことによって ControlStyle を作成します。この結果、コントロールのスタイルはビューステートにアクセスできます。カスタマイズされた状態管理をコントロールのスタイル プロパティにデリゲートする方法の例については、「template 宣言のあるデータ連結コントロールのサンプル」を参照してください。
ControlStyle プロパティの既定の型は Style ですが、次の例に示すように、WebControl.CreateControlStyle メソッドをオーバーライドすることによって、Web サーバー コントロールは、コントロール スタイルを Style から派生するどのようなクラスにも設定できます。
protected override Style CreateControlStyle()
{
// Note that the constructor of Style takes ViewState as an
// argument.
TableStyle style = new TableStyle(ViewState);
// Set up default initial state.
style.CellSpacing = 0;
return style;
}
[Visual Basic]
Protected Overrides Function CreateControlStyle() As Style
' Note that the constructor of Style takes ViewState as an
' argument.
Dim style As New TableStyle(ViewState)
' Set up default initial state.
style.CellSpacing = 0
Return style
End Function
基本の Style 型に加えて、System.Web.UI.WebControls 名前空間は、TableStyle や TableItemStyle などの他のスタイル型を提供します。Style や Style から派生するクラスからの派生、およびメンバのオーバーライドや追加によって、追加する厳密に型指定されたスタイルを定義できます。WebControl が Style のサブプロパティを最上位レベルのプロパティとして公開するように、カスタム スタイル型のサブプロパティを最上位レベルのプロパティとして公開できます。たとえば、Table は、ControlStyle を TableStyle として設定し、CellPadding、CellSpacing、Gridlines などの TableStyle のサブプロパティを最上位レベルのプロパティとして公開します。「template 宣言のあるデータ連結コントロールのサンプル」の次のコード片は、TemplatedList
カスタム コントロールが ControlStyle の ControlStyle サブプロパティを最上位レベルのプロパティとして公開する方法を示しています。
public virtual int CellPadding {
get {
if (ControlStyleCreated == false) {
return -1;
}
return ((TableStyle)ControlStyle).CellPadding;
}
set {
((TableStyle)ControlStyle).CellPadding = value;
}
}
[Visual Basic]
Public Overridable Property CellPadding() As Integer
Get
If ControlStyleCreated = False Then
Return - 1
End If
Return CType(ControlStyle, TableStyle).CellPadding
End Get
Set
CType(ControlStyle, TableStyle).CellPadding = value
End Set
End Property
WebControl の次のメソッドによって、コントロールのユーザーは、コントロールの ControlStyle を変更できます。
- WebControl.ApplyStyle メソッドは、指定したスタイルを ControlStyle にコピーし、既存の要素に上書きします。
- WebControl.MergeStyle メソッドは、指定したスタイルを既存の要素に上書きすることなく ControlStyle とマージします。
これらのメソッドの使用例については、「template 宣言のあるデータ連結コントロールのサンプル」を参照してください。
子コントロールの追加のスタイル プロパティの公開
ControlStyle プロパティは Web サーバー コントロール全体のスタイルを制御しますが、複合 Web サーバー コントロール (子コントロールを備えた Web サーバー コントロール) も、子コントロールに適用する追加のスタイル プロパティを公開できます。コントロールは、クライアントへの往復の過程で子コントロールに適用する追加スタイルを保持するために、カスタマイズされた状態管理を実装する必要があります。子コントロールに適用する追加のスタイルを提供する主要な手順を次に示します。
子コントロールのスタイルを公開するには、次のようにします。
Style から派生する 1 つ以上のプロパティを定義します。「template 宣言のあるデータ連結コントロールのサンプル」で説明する
TemplatedList
カスタム コントロールは、次のコード片に示すように、追加のスタイルを公開します。なお、この場合、新しい Style オブジェクトが作成されるときに、コントロールの ViewState は Style コンストラクタに渡されません。コントロールの ViewState が Style コンストラクタに渡されるのは、コントロールの ControlStyle プロパティを作成する場合だけであり、Style 型のその他のプロパティの場合は渡されません。なお、コントロールは、ビューステートの追跡をスタイル プロパティ自身にデリゲートします。public virtual TableItemStyle AlternatingItemStyle { get { if (alternatingItemStyle == null) { alternatingItemStyle = new TableItemStyle(); if (IsTrackingViewState) ((IStateManager)alternatingItemStyle).TrackViewState(); } return alternatingItemStyle; } } [Visual Basic] Public Overridable ReadOnly Property AlternatingItemStyle() As TableItemStyle Get If _alternatingItemStyle Is Nothing Then _alternatingItemStyle = New TableItemStyle() If IsTrackingViewState Then CType(_alternatingItemStyle, IStateManager).TrackViewState() End If End If Return _alternatingItemStyle End Get End Property
スタイルを子コントロールに適用します。例とスタイルのマージ方法については、「template 宣言のあるデータ連結コントロールのサンプル」の
PrepareControlHierarchy
メソッドを参照してください。サンプルに示すように、レンダリング フェーズでスタイルを子コントロールに適用し、ビューステートが永続的に続かないようにしてください。SaveViewState メソッドをオーバーライドして追加のスタイル プロパティを ViewState に保存します。Style オブジェクトは自身の状態を管理するため、コントロールは、スタイル プロパティの SaveViewState を呼び出して ViewState プロパティへの追加を要するオブジェクトを取得する必要があります。「template 宣言のあるデータ連結コントロールのサンプル」の次の例に、コントロールがカスタマイズされた状態管理をスタイル プロパティにデリゲートする方法を示します。
protected override object SaveViewState() { // Customized state management to handle saving // state of contained objects such as styles. object baseState = base.SaveViewState(); object itemStyleState = (itemStyle != null) ? ((IStateManager)itemStyle).SaveViewState() : null; object selectedItemStyleState = (selectedItemStyle != null) ? ((IStateManager)selectedItemStyle).SaveViewState() : null; object alternatingItemStyleState = (alternatingItemStyle != null) ? ((IStateManager)alternatingItemStyle).SaveViewState() : null; object[] myState = new object[4]; myState[0] = baseState; myState[1] = itemStyleState; myState[2] = selectedItemStyleState; myState[3] = alternatingItemStyleState; return myState; } [Visual Basic] Protected Overrides Function SaveViewState() As Object ' Customized state management to handle saving ' state of contained objects such as styles. Dim baseState As Object = MyBase.SaveViewState() Dim itemStyleState As Object Dim selectedItemStyleState As Object Dim alternatingItemStyleState As Object If Not (_itemStyle Is Nothing) Then itemStyleState = CType(_itemStyle, IStateManager).SaveViewState() Else itemStyleState = Nothing End If If Not (_selectedItemStyle Is Nothing) Then selectedItemStyleState = CType(_selectedItemStyle, IStateManager).SaveViewState() Else selectedItemStyleState = Nothing End If If Not (_alternatingItemStyle Is Nothing) Then alternatingItemStyleState = CType(_alternatingItemStyle, IStateManager).SaveViewState() Else alternatingItemStyleState = Nothing End If Dim myState(4) As Object myState(0) = baseState myState(1) = itemStyleState myState(2) = selectedItemStyleState myState(3) = alternatingItemStyleState Return myState End Function
LoadViewState メソッドをオーバーライドして ViewState から追加のスタイル プロパティの復元をカスタマイズします。ViewState に追加された追加のオブジェクトは、追加された順序と同じ順序で取得する必要があります。「template 宣言のあるデータ連結コントロールのサンプル」の次の例で示すのは、コントロールがカスタマイズされた状態復元をスタイル プロパティにデリゲートする方法です。
protected override void LoadViewState(object savedState) { // Customized state management to handle // state restoration of contained objects. if (savedState != null) { object[] myState = (object[])savedState; if (myState[0] != null) base.LoadViewState(myState[0]); if (myState[1] != null) ((IStateManager)ItemStyle).LoadViewState(myState[1]); if (myState[2] != null) ((IStateManager)SelectedItemStyle).LoadViewState(myState[2]); if (myState[3] != null) ((IStateManager)AlternatingItemStyle).LoadViewState(myState[3]); } } [Visual Basic] Protected Overrides Sub LoadViewState(savedState As Object) ' Customized state management to handle saving ' state of contained objects. If Not (savedState Is Nothing) Then Dim myState As Object() = CType(savedState, Object()) If Not (myState(0) Is Nothing) Then MyBase.LoadViewState(myState(0)) End If If Not (myState(1) Is Nothing) Then CType(ItemStyle, IStateManager).LoadViewState(myState(1)) End If If Not (myState(2) Is Nothing) Then CType(SelectedItemStyle, IStateManager).LoadViewState(myState(2)) End If If Not (myState(3) Is Nothing) Then CType(AlternatingItemStyle, IStateManager).LoadViewState(myState(3)) End If End If End Sub
子コントロールに適用されたスタイル プロパティを公開するコントロールのサンプルについては、「template 宣言のあるデータ連結コントロールのサンプル」を参照してください。