子控制項的具型別樣式範例
更新:2007 年 11 月
本範例示範如何建立名為 StyledRegister 的控制項,這個控制項會在複合控制項 (Composite Control) 中實作強型別 (Strongly Typed) 樣式屬性。這些屬性可讓網頁開發人員自訂複合控制項之子控制項的外觀。具型別樣式也可讓複合控制項輕鬆地縮放。當更多子控制項加入至複合控制項時,在複合控制項中公開 (Expose) 每個子控制項的多個屬性將變成無法管理。因此,您可以將多個屬性封裝在單一樣式屬性中。
範例中的 StyledRegister 控制項類似於複合 Web 控制項範例中所描述的 Register 控制項。StyledRegister 控制項有兩個 TextBox 子控制項和一個 Button 子控制項。StyledRegister 類別會公開 ButtonStyle 和 TextBoxStyle 屬性,可讓網頁開發人員設定 Font、ForeColor,以及 TextBox 子系與 Button 控制項其他樣式相關的屬性。
網頁開發人員可以設定 StyledRegister 控制項中,控制項的 Font-Names、ForeColor 和 BackColor 屬性,如下列範例所示:
<aspSample:StyledRegister ID="StyledRegister1" >
<TextBoxStyle Font-Names="Arial" BorderStyle="Solid"
ForeColor="#804000"></TextBoxStyle>
<ButtonStyle Font-Names="Arial" BorderStyle="Outset"
BackColor="Silver"></ButtonStyle>
</aspSample:StyledRegister>
如前一個範例所示,具型別樣式屬性會當做子項目在控制項標記中保存。如需實作以這個方式保存之屬性的詳細資訊,請參閱伺服器控制項屬性範例中 Author 屬性的實作。
具型別樣式是 Style 型別或衍生自 Style 之型別的屬性。Style 類別會公開與外觀相關的屬性,例如 Font、ForeColor 和 BackColor。WebControl 類別的 ControlStyle 屬性其型別為 Style。Web 控制項的 Font、ForeColor 和 BackColor 屬性是 ControlStyle 屬性的子屬性,雖然這些屬性也會當做 WebControl 類別的最上層屬性公開。
由於 Style 類別具有子屬性,Style 型別的屬性需要自訂狀態管理,如自訂屬性狀態管理範例所述。具型別樣式的實作詳細資料會在本主題稍後的「程式碼討論」章節中說明。
StyledRegister 控制項的程式碼清單
' StyledRegister.vb
Option Strict On
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace Samples.AspNet.VB.Controls
< _
AspNetHostingPermission(SecurityAction.Demand, _
Level:=AspNetHostingPermissionLevel.Minimal), _
AspNetHostingPermission(SecurityAction.InheritanceDemand, _
Level:=AspNetHostingPermissionLevel.Minimal), _
DefaultEvent("Submit"), _
DefaultProperty("ButtonText"), _
ToolboxData("<{0}:Register runat=""server""> </{0}:Register>") _
> _
Public Class StyledRegister
Inherits CompositeControl
Private submitButton As Button
Private nameTextBox As TextBox
Private nameLabel As Label
Private emailTextBox As TextBox
Private emailLabel As Label
Private emailValidator As RequiredFieldValidator
Private nameValidator As RequiredFieldValidator
Private Shared ReadOnly EventSubmitKey As New Object()
Private buttonStyleValue As Style
Private textBoxStyleValue As Style
#Region "Properties delegated to child controls"
< _
Bindable(True), _
Category("Appearance"), _
DefaultValue(""), _
Description("The text to display on the Button.") _
> _
Public Property ButtonText() As String
Get
EnsureChildControls()
Return submitButton.Text
End Get
Set(ByVal value As String)
EnsureChildControls()
submitButton.Text = value
End Set
End Property
< _
Bindable(True), _
Category("Default"), _
DefaultValue(""), _
Description("The user name.") _
> _
Public Property Name() As String
Get
EnsureChildControls()
Return nameTextBox.Text
End Get
Set(ByVal value As String)
EnsureChildControls()
nameTextBox.Text = value
End Set
End Property
< _
Bindable(True), _
Category("Appearance"), _
DefaultValue(""), _
Description("The error message of the name validator.") _
> _
Public Property NameErrorMessage() As String
Get
EnsureChildControls()
Return nameValidator.ErrorMessage
End Get
Set(ByVal value As String)
EnsureChildControls()
nameValidator.ErrorMessage = value
nameValidator.ToolTip = value
End Set
End Property
< _
Bindable(True), _
Category("Appearance"), _
DefaultValue(""), _
Description("The text for the name Label.") _
> _
Public Property NameLabelText() As String
Get
EnsureChildControls()
Return nameLabel.Text
End Get
Set(ByVal value As String)
EnsureChildControls()
nameLabel.Text = value
End Set
End Property
< _
Bindable(True), _
Category("Default"), _
DefaultValue(""), _
Description("The e-mail address.") _
> _
Public Property Email() As String
Get
EnsureChildControls()
Return emailTextBox.Text
End Get
Set(ByVal value As String)
EnsureChildControls()
emailTextBox.Text = value
End Set
End Property
< _
Bindable(True), _
Category("Appearance"), _
DefaultValue(""), _
Description("Error message of the e-mail validator.") _
> _
Public Property EmailErrorMessage() As String
Get
EnsureChildControls()
Return emailValidator.ErrorMessage
End Get
Set(ByVal value As String)
EnsureChildControls()
emailValidator.ErrorMessage = value
emailValidator.ToolTip = value
End Set
End Property
< _
Bindable(True), _
Category("Appearance"), _
DefaultValue(""), _
Description("The text for the e-mail Label.") _
> _
Public Property EmailLabelText() As String
Get
EnsureChildControls()
Return emailLabel.Text
End Get
Set(ByVal value As String)
EnsureChildControls()
emailLabel.Text = value
End Set
End Property
#End Region
#Region "Typed Style properties"
< _
Category("Styles"), _
DefaultValue(GetType(Style), Nothing), _
DesignerSerializationVisibility( _
DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty), _
Description( _
"The strongly typed style for the Button child control.") _
> _
Public Overridable ReadOnly Property ButtonStyle() As Style
Get
If buttonStyleValue Is Nothing Then
buttonStyleValue = New Style
If IsTrackingViewState Then
CType(buttonStyleValue, _
IStateManager).TrackViewState()
End If
End If
Return buttonStyleValue
End Get
End Property
< _
Category("Styles"), _
DefaultValue(GetType(Style), Nothing), _
DesignerSerializationVisibility( _
DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty), _
Description( _
"The strongly typed style for the TextBox child control.") _
> _
Public Overridable ReadOnly Property TextBoxStyle() As Style
Get
If textBoxStyleValue Is Nothing Then
textBoxStyleValue = New Style
If IsTrackingViewState Then
CType(textBoxStyleValue, _
IStateManager).TrackViewState()
End If
End If
Return textBoxStyleValue
End Get
End Property
#End Region
#Region "Event definition"
< _
Category("Action"), _
Description("Raised when the user clicks the button.") _
> _
Public Custom Event Submit As EventHandler
AddHandler(ByVal value As EventHandler)
Events.AddHandler(EventSubmitKey, value)
End AddHandler
RemoveHandler(ByVal value As EventHandler)
Events.RemoveHandler(EventSubmitKey, value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, _
ByVal e As System.EventArgs)
CType(Events(EventSubmitKey), _
EventHandler).Invoke(sender, e)
End RaiseEvent
End Event
' The method that raises the Submit event.
Protected Overridable Sub OnSubmit(ByVal e As EventArgs)
Dim submitHandler As EventHandler = _
CType(Events(EventSubmitKey), EventHandler)
If submitHandler IsNot Nothing Then
submitHandler(Me, e)
End If
End Sub
' Handles the Click event of the Button and raises
' the Submit event.
Private Sub submitButton_Click(ByVal source As Object, _
ByVal e As EventArgs)
OnSubmit(EventArgs.Empty)
End Sub
#End Region
#Region "Overridden methods"
Protected Overrides Sub CreateChildControls()
Controls.Clear()
nameLabel = New Label()
nameTextBox = New TextBox()
nameTextBox.ID = "nameTextBox"
nameValidator = New RequiredFieldValidator()
nameValidator.ID = "validator1"
nameValidator.ControlToValidate = nameTextBox.ID
nameValidator.Text = "*"
nameValidator.Display = ValidatorDisplay.Static
emailLabel = New Label()
emailTextBox = New TextBox()
emailTextBox.ID = "emailTextBox"
emailValidator = New RequiredFieldValidator()
emailValidator.ID = "validator2"
emailValidator.ControlToValidate = emailTextBox.ID
emailValidator.Text = "*"
emailValidator.Display = ValidatorDisplay.Static
submitButton = New Button()
submitButton.ID = "button1"
AddHandler submitButton.Click, _
AddressOf submitButton_Click
Me.Controls.Add(nameLabel)
Me.Controls.Add(nameTextBox)
Me.Controls.Add(nameValidator)
Me.Controls.Add(emailLabel)
Me.Controls.Add(emailTextBox)
Me.Controls.Add(emailValidator)
Me.Controls.Add(submitButton)
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
AddAttributesToRender(writer)
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, _
"1", False)
writer.RenderBeginTag(HtmlTextWriterTag.Table)
If buttonStyleValue IsNot Nothing Then
submitButton.ApplyStyle(buttonStyleValue)
End If
If textBoxStyleValue IsNot Nothing Then
nameTextBox.ApplyStyle(textBoxStyleValue)
emailTextBox.ApplyStyle(textBoxStyleValue)
End If
writer.RenderBeginTag(HtmlTextWriterTag.Tr)
writer.RenderBeginTag(HtmlTextWriterTag.Td)
nameLabel.RenderControl(writer)
writer.RenderEndTag() ' Renders the </td> tag.
writer.RenderBeginTag(HtmlTextWriterTag.Td)
nameTextBox.RenderControl(writer)
writer.RenderEndTag() 'closing Td
writer.RenderBeginTag(HtmlTextWriterTag.Td)
nameValidator.RenderControl(writer)
writer.RenderEndTag() 'closing Td
writer.RenderEndTag() 'closing Tr
writer.RenderBeginTag(HtmlTextWriterTag.Tr)
writer.RenderBeginTag(HtmlTextWriterTag.Td)
emailLabel.RenderControl(writer)
writer.RenderEndTag() 'closing Td
writer.RenderBeginTag(HtmlTextWriterTag.Td)
emailTextBox.RenderControl(writer)
writer.RenderEndTag() 'closing Td
writer.RenderBeginTag(HtmlTextWriterTag.Td)
emailValidator.RenderControl(writer)
writer.RenderEndTag() 'closing Td
writer.RenderEndTag() 'closing Tr
writer.RenderBeginTag(HtmlTextWriterTag.Tr)
writer.AddAttribute(HtmlTextWriterAttribute.Colspan, _
"2", False)
writer.AddAttribute(HtmlTextWriterAttribute.Align, _
"right", False)
writer.RenderBeginTag(HtmlTextWriterTag.Td)
submitButton.RenderControl(writer)
writer.RenderEndTag() 'closing Td
writer.RenderBeginTag(HtmlTextWriterTag.Td)
writer.Write(" ")
writer.RenderEndTag() 'closing Td
writer.RenderEndTag() 'closing Tr
writer.RenderEndTag() 'closing Table
End Sub
Protected Overrides Sub RecreateChildControls()
EnsureChildControls()
End Sub
#End Region
#Region "Custom state management"
Protected Overrides Sub LoadViewState( _
ByVal savedState As Object)
If savedState is Nothing Then
MyBase.LoadViewState(Nothing)
Return
Else
Dim t As Triplet = TryCast(savedState, Triplet)
If t IsNot Nothing Then
' Always invoke LoadViewState on the base class even if
' the saved state is null.
MyBase.LoadViewState(t.First)
If t.Second IsNot Nothing Then
CType(buttonStyleValue, _
IStateManager).LoadViewState(t.Second)
End If
If t.Third IsNot Nothing Then
CType(textBoxStyleValue, _
IStateManager).LoadViewState(t.Third)
End If
Else
Throw New ArgumentException("Invalid view state .")
End If
End If
End Sub
Protected Overrides Function SaveViewState() As Object
Dim baseState As Object = MyBase.SaveViewState
Dim buttonStyleState As Object = Nothing
Dim textBoxStyleState As Object = Nothing
If buttonStyleValue IsNot Nothing Then
buttonStyleState = CType(buttonStyleValue, _
IStateManager).SaveViewState
End If
If textBoxStyleValue IsNot Nothing Then
textBoxStyleState = CType(textBoxStyleValue, _
IStateManager).SaveViewState
End If
Return New Triplet(baseState, buttonStyleState, _
textBoxStyleState)
End Function
Protected Overrides Sub TrackViewState()
MyBase.TrackViewState()
If buttonStyleValue IsNot Nothing Then
CType(buttonStyleValue, IStateManager).TrackViewState()
End If
If textBoxStyleValue IsNot Nothing Then
CType(textBoxStyleValue, IStateManager).TrackViewState()
End If
End Sub
#End Region
End Class
End Namespace
// StyledRegister.cs
using System;
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Samples.AspNet.CS.Controls
{
[
AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level=AspNetHostingPermissionLevel.Minimal),
DefaultEvent("Submit"),
DefaultProperty("ButtonText"),
ToolboxData(
"<{0}:StyledRegister runat=\"server\"> </{0}:StyledRegister>"),
]
public class StyledRegister : CompositeControl
{
private Button submitButton;
private TextBox nameTextBox;
private Label nameLabel;
private TextBox emailTextBox;
private Label emailLabel;
private RequiredFieldValidator _emailValidator;
private RequiredFieldValidator _nameValidator;
private Style _buttonStyle;
private Style _textBoxStyle;
private static readonly object EventSubmitKey = new object();
#region Properties delegated to child controls
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text to display on the button.")
]
public string ButtonText
{
get
{
EnsureChildControls();
return submitButton.Text;
}
set
{
EnsureChildControls();
submitButton.Text = value;
}
}
[
Bindable(true),
Category("Default"),
DefaultValue(""),
Description("The user name.")
]
public string Name
{
get
{
EnsureChildControls();
return nameTextBox.Text;
}
set
{
EnsureChildControls();
nameTextBox.Text = value;
}
}
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description(
"The error message of the name validator.")
]
public string NameErrorMessage
{
get
{
EnsureChildControls();
return _nameValidator.ErrorMessage;
}
set
{
EnsureChildControls();
_nameValidator.ErrorMessage = value;
_nameValidator.ToolTip = value;
}
}
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text for the name label.")
]
public string NameLabelText
{
get
{
EnsureChildControls();
return nameLabel.Text;
}
set
{
EnsureChildControls();
nameLabel.Text = value;
}
}
[
Bindable(true),
Category("Default"),
DefaultValue(""),
Description("The e-mail address.")
]
public string Email
{
get
{
EnsureChildControls();
return emailTextBox.Text;
}
set
{
EnsureChildControls();
emailTextBox.Text = value;
}
}
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description(
"Error message of the e-mail validator.")
]
public string EmailErrorMessage
{
get
{
EnsureChildControls();
return _emailValidator.ErrorMessage;
}
set
{
EnsureChildControls();
_emailValidator.ErrorMessage = value;
_emailValidator.ToolTip = value;
}
}
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text for the e-mail label.")
]
public string EmailLabelText
{
get
{
EnsureChildControls();
return emailLabel.Text;
}
set
{
EnsureChildControls();
emailLabel.Text = value;
}
}
#endregion
#region Typed Style properties
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"The strongly typed style for the Button child control.")
]
public virtual Style ButtonStyle
{
get
{
if (_buttonStyle == null)
{
_buttonStyle = new Style();
if (IsTrackingViewState)
{
((IStateManager)_buttonStyle).TrackViewState();
}
}
return _buttonStyle;
}
}
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"The strongly typed style for the TextBox child control.")
]
public virtual Style TextBoxStyle
{
get
{
if (_textBoxStyle == null)
{
_textBoxStyle = new Style();
if (IsTrackingViewState)
{
((IStateManager)_textBoxStyle).TrackViewState();
}
}
return _textBoxStyle;
}
}
#endregion
#region Event definition
// The Submit event.
[
Category("Action"),
Description("Raised when the user clicks the button")
]
public event EventHandler Submit
{
add
{
Events.AddHandler(EventSubmitKey, value);
}
remove
{
Events.RemoveHandler(EventSubmitKey, value);
}
}
// The method that raises theSubmit event.
protected virtual void OnSubmit(EventArgs e)
{
EventHandler SubmitHandler =
(EventHandler)Events[EventSubmitKey];
if (SubmitHandler != null)
{
SubmitHandler(this, e);
}
}
// Handles the Click event of the Button and raises
// the Submit event.
private void _button_Click(object source, EventArgs e)
{
OnSubmit(EventArgs.Empty);
}
#endregion
#region Overridden methods
protected override void RecreateChildControls()
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
Controls.Clear();
nameLabel = new Label();
nameTextBox = new TextBox();
nameTextBox.ID = "nameTextBox";
_nameValidator = new RequiredFieldValidator();
_nameValidator.ID = "validator1";
_nameValidator.ControlToValidate = nameTextBox.ID;
_nameValidator.Text = "*";
_nameValidator.Display = ValidatorDisplay.Static;
emailLabel = new Label();
emailTextBox = new TextBox();
emailTextBox.ID = "emailTextBox";
_emailValidator = new RequiredFieldValidator();
_emailValidator.ID = "validator2";
_emailValidator.ControlToValidate = emailTextBox.ID;
_emailValidator.Text = "*";
_emailValidator.Display = ValidatorDisplay.Static;
submitButton = new Button();
submitButton.ID = "button1";
submitButton.Click += new EventHandler(_button_Click);
this.Controls.Add(nameLabel);
this.Controls.Add(nameTextBox);
this.Controls.Add(_nameValidator);
this.Controls.Add(emailLabel);
this.Controls.Add(emailTextBox);
this.Controls.Add(_emailValidator);
this.Controls.Add(submitButton);
}
protected override void Render(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding,
"1", false);
writer.RenderBeginTag(HtmlTextWriterTag.Table);
if (_buttonStyle != null)
{
submitButton.ApplyStyle(ButtonStyle);
}
if (_textBoxStyle != null)
{
nameTextBox.ApplyStyle(TextBoxStyle);
emailTextBox.ApplyStyle(TextBoxStyle);
}
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
nameLabel.RenderControl(writer);
writer.RenderEndTag(); // Closing td.
writer.RenderBeginTag(HtmlTextWriterTag.Td);
nameTextBox.RenderControl(writer);
writer.RenderEndTag(); //Closing td.
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_nameValidator.RenderControl(writer);
writer.RenderEndTag(); //Closing td.
writer.RenderEndTag(); //Closing tr.
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
emailLabel.RenderControl(writer);
writer.RenderEndTag(); //Closing td.
writer.RenderBeginTag(HtmlTextWriterTag.Td);
emailTextBox.RenderControl(writer);
writer.RenderEndTag(); //Closing td.
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_emailValidator.RenderControl(writer);
writer.RenderEndTag(); //Closing td.
writer.RenderEndTag(); //Closing tr.
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.AddAttribute(HtmlTextWriterAttribute.Colspan,
"2", false);
writer.AddAttribute(HtmlTextWriterAttribute.Align,
"right", false);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
submitButton.RenderControl(writer);
writer.RenderEndTag(); //closing td.
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(" ");
writer.RenderEndTag(); //closing td.
writer.RenderEndTag(); //closing tr.
writer.RenderEndTag(); //closing table.
}
#endregion
#region Custom state management
protected override void LoadViewState(object savedState)
{
if (savedState == null)
{
base.LoadViewState(null);
return;
}
else
{
Triplet t = savedState as Triplet;
if (t != null)
{
// Always invoke LoadViewState on the base class even if
// the saved state is null.
base.LoadViewState(t.First);
if ((t.Second) != null)
{
((IStateManager)ButtonStyle).LoadViewState(t.Second);
}
if ((t.Third) != null)
{
((IStateManager)TextBoxStyle).LoadViewState(t.Third);
}
}
else
{
throw new ArgumentException("Invalid view state .");
}
}
}
protected override object SaveViewState()
{
object baseState = base.SaveViewState();
object buttonStyleState = null;
object textBoxStyleState = null;
if (_buttonStyle != null)
{
buttonStyleState =
((IStateManager)_buttonStyle).SaveViewState();
}
if (_textBoxStyle != null)
{
textBoxStyleState =
((IStateManager)_textBoxStyle).SaveViewState();
}
return new Triplet(baseState,
buttonStyleState, textBoxStyleState);
}
protected override void TrackViewState()
{
base.TrackViewState();
if (_buttonStyle != null)
{
((IStateManager)_buttonStyle).TrackViewState();
}
if (_textBoxStyle != null)
{
((IStateManager)_textBoxStyle).TrackViewState();
}
}
#endregion
}
}
程式碼討論
StyledRegister 控制項示範下列對子控制項實作具型別樣式的主要步驟:
由於 Style 型別會實作 IStateManager 介面,定義 Style 型別之屬性的模式會和自訂屬性狀態管理範例中所描述的一樣。您會將具型別樣式屬性定義為,存放在私用欄位中的唯讀屬性。在屬性存取子 (Accessor) 中,只有當對應於屬性的欄位是 null (在 Visual Basic 中為 Nothing) 時,才可以建立新的 Style 執行個體。如果控制項已啟動狀態追蹤,您可以呼叫新建立之 Style 執行個體的 TrackViewState 方法。StyledRegister 的 ButtonStyle 和 TextBoxStyle 屬性,便是以這個技術進行定義的。
同樣地,StyledRegister 中狀態管理方法的實作和自訂屬性狀態管理範例中說明的一樣。在控制項覆寫的 TrackViewState 方法中,可以呼叫基底類別的 TrackViewState 方法,並呼叫每個樣式屬性的 TrackViewState 方法。在覆寫的 SaveViewState 方法中,可以呼叫基底類別的 SaveViewState,並呼叫每個樣式屬性的 SaveViewState。從 SaveViewState 傳回的狀態表示結合基底類別和樣式屬性的組合狀態。為了容易在 LoadViewState 方法中進行擷取,StyledRegister 控制項會使用 Triplet 物件儲存組合狀態。LoadViewState 方法會執行與 SaveViewState 方法相反的動作,並在回傳時將狀態載入基底類別和具型別樣式。
實作具型別樣式的最後一個步驟是將樣式套用至子控制項。StyledRegister 控制項會在儲存檢視狀態之後,在呈現階段時執行這個步驟,如此對應於具型別樣式的狀態就不會在子控制項的檢視狀態中儲存。如果在啟動狀態追蹤時,具型別樣式已套用至子控制項,則這些樣式應該在子控制項的檢視狀態中儲存。這樣做會降低執行效能,因為具型別樣式屬性會自行管理其狀態。下列節錄自 StyledRegister 控制項 Render 方法的程式碼,將示範在呈現階段中套用樣式的實作模式。
protected override void Render(HtmlTextWriter writer)
{
// Add code here to set up rendering.
if (_buttonStyle != null)
{
_button.ApplyStyle(ButtonStyle);
}
if (_textBoxStyle != null)
{
_nameTextBox.ApplyStyle(TextBoxStyle);
_emailTextBox.ApplyStyle(TextBoxStyle);
}
// Add code here to continue rendering.
}
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
' Add code here to set up rendering.
If buttonStyleValue IsNot Nothing Then
submitButton.ApplyStyle(buttonStyleValue)
End If
If textBoxStyleValue IsNot Nothing Then
nameTextBox.ApplyStyle(textBoxStyleValue)
emailTextBox.ApplyStyle(textBoxStyleValue)
End If
' Add code here to continue rendering.
End Sub
StyledRegister 控制項的測試頁
下列範例顯示使用 StyledRegister 控制項的 .aspx 網頁。在 Submit 事件處理常式中應該加入程式碼,以便將註冊資料輸入資料庫或寫入使用者電腦上的 Cookie。在實際執行應用程式中,您也需要檢查指令碼插入 (Script Injection) 攻擊。如需詳細資訊,請參閱指令碼攻擊概觀。
<%@ Page Language="VB"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Label1.Visible = False
End Sub
Sub StyledRegister_Submit(ByVal sender As Object, _
ByVal e As EventArgs)
Label1.Text = String.Format( _
"Thank you, {0}! You are registered.", _
StyledRegister1.Name)
Label1.Visible = True
StyledRegister1.Visible = False
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" >
<title>
StyledRegister Control Test Page
</title>
</head>
<body>
<form id="form1" >
<aspSample:StyledRegister ButtonText="Register"
OnSubmit="StyledRegister_Submit" ID="StyledRegister1"
Runat="server" NameLabelText="Name:" EmailLabelText="Email:"
EmailErrorMessage="You must enter your e-mail address."
NameErrorMessage="You must enter your name."
BorderStyle="Solid" BorderWidth="1px" BackColor="#E0E0E0">
<TextBoxStyle Font-Names="Arial" BorderStyle="Solid"
ForeColor="#804000"></TextBoxStyle>
<ButtonStyle Font-Names="Arial" BorderStyle="Outset"
BackColor="Silver"></ButtonStyle>
</aspSample:StyledRegister>
<br />
<asp:Label ID="Label1" Runat="server" Text="Label">
</asp:Label>
<asp:ValidationSummary ID="ValidationSummary1"
Runat="server" DisplayMode="List" />
</form>
</body>
</html>
<%@ Page Language="C#"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
void Page_Load(object sender, EventArgs e)
{
Label1.Visible = false;
}
void StyledRegister_Submit(object sender, EventArgs e)
{
Label1.Text = String.Format("Thank you, {0}! You are registered.",
StyledRegister1.Name);
Label1.Visible = true;
StyledRegister1.Visible = false;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" >
<title>
StyledRegister Control Test Page
</title>
</head>
<body>
<form id="form1" >
<aspSample:StyledRegister ButtonText="Register"
OnSubmit="StyledRegister_Submit" ID="StyledRegister1"
Runat="server" NameLabelText="Name:" EmailLabelText="Email:"
EmailErrorMessage="You must enter your e-mail address."
NameErrorMessage="You must enter your name."
BorderStyle="Solid" BorderWidth="1px" BackColor="#E0E0E0">
<TextBoxStyle Font-Names="Arial" BorderStyle="Solid"
ForeColor="#804000"></TextBoxStyle>
<ButtonStyle Font-Names="Arial" BorderStyle="Outset"
BackColor="Silver"></ButtonStyle>
</aspSample:StyledRegister>
<br />
<asp:Label ID="Label1" Runat="server" Text="Label">
</asp:Label>
<asp:ValidationSummary ID="ValidationSummary1"
Runat="server" DisplayMode="List" />
</form>
</body>
</html>
建置及使用範例
如需編譯及使用自訂控制項範例的詳細資訊,請參閱建置自訂伺服器控制項範例。