Поделиться через


Типизированные стили для дочерних элементов управления

Обновлен: Ноябрь 2007

В данном примере показано, как создавать элемент управления с именем StyledRegister, который использует свойства строго типизированных стилей в составном элементе управления. Эти свойства позволяют разработчику страниц настраивать отображение дочерних элементов управления составного элемента управления. Типизированные стили также позволяют легко масштабировать составные элементы управления. Чем больше дочерних элементов управления добавляется в составной элемент управления, тем сложнее становится управление многочисленными свойствами каждого дочернего элемента управления. Вместо этого можно заключить множество свойств в едином свойстве стиля.

Элемент управления StyledRegister в этом примере похож на элемент управления Register, описанный в разделе Пример составного веб-элемента управления. Элемент управления StyledRegister имеет два дочерних элемента управления: TextBox и Button. Класс StyledRegister предоставляет свойства ButtonStyle и TextBoxStyle, чтобы позволить разработчику страниц задавать свойства Font, ForeColor и другие связанные со стилем свойства дочерних элементов управления TextBox и Button.

Разработчик страниц может задавать свойства Font-Names, ForeColor и BackColor элементов управления в элементе управления StyledRegister, как это показано в следующем примере:

<aspSample:StyledRegister ID="StyledRegister1" runat="server">
  <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. Свойство ControlStyle класса WebControl относится к типу Style. Свойства 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("&nbsp")
            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("&nbsp;");
            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 или типов, наследованных от Style.

  • Реализация управления состоянием свойств стилей.

  • Применение стилей к дочерним элементам управления.

Так как тип Style использует интерфейс IStateManager, то шаблон для определения свойства типа Style идентичен описанному в разделе Пример управления состоянием настраиваемого свойства. Определите свойство типизированного стиля как свойство, предназначенное только для чтения, хранящееся в отдельном поле. В доступе к свойству создается новый экземпляр Style только, если соответствующее свойству поле имеет значение null (Nothing в Visual Basic). Если элемент управления начал отслеживание состояния, то необходимо вызвать метод TrackViewState для вновь созданного экземпляра Style. Свойства ButtonStyle и TextBoxStyle элемента управления StyledRegister задаются при помощи этой техники.

Реализация методов управления состоянием в элементе управления StyledRegister идентично описанному в разделе Пример управления состоянием настраиваемого свойства. В переопределенном методе TrackViewState элемента управления вызывается метод TrackViewState для базового класса и метод TrackViewState для каждого свойства стиля. В переопределенном методе SaveViewState элемента управления вызывается метод SaveViewState для базового класса и метод SaveViewState для каждого свойства стиля. Метод SaveViewState возвращает состояние, отображающее комбинированное состояние базового класса и свойств стиля. Для простоты извлечения в методе LoadViewState элемент управления StyledRegister использует объект Triplet для сохранения комбинированного состояния. Метод LoadViewState выполняет противоположные методу SaveViewState действия и загружает состояние в базовый класс и в типизированные стили при обратной передаче.

Последним шагом в реализации типизированных стилей является применение стилей к дочерним элементам управления. Элемент управления StyledRegister осуществляет этот шаг в фазе отображения после сохранения состояния просмотра так, что соответствующее типизированным стилям состояние не сохраняется в состоянии просмотра дочерних элементов управления. Если типизированные стили были применены к дочерним элементам управления при включенном отслеживании состояния, то эти стили будут сохранены в состоянии просмотра дочерних элементов управления. Это будет неэффективным, так как свойства типизированных стилей управляют своим состоянием. Следующий фрагмент кода метода Render элемента управления StyledRegister показывает применение шаблона для использования стилей в фазе отображения:

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

В следующем примере показана ASPX-страница, использующая элемент управления StyledRegister. В обработчике событий Submit добавьте код, чтобы вводить регистрационные данные в базу данных или записывать файлы cookie на пользовательский компьютер. В реальном приложении необходимо также проверять код на наличие атак путем внедрения сценариев. Дополнительные сведения см. в разделе Общие сведения об использовании сценариев.

<%@ Page Language="VB"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    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" runat="server">
    <title>
      StyledRegister Control Test Page
    </title>
  </head>
  <body>
    <form id="form1" runat="server">
      <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 runat="server">
  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" runat="server">
    <title>
      StyledRegister Control Test Page
    </title>
  </head>
  <body>
    <form id="form1" runat="server">
      <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>

Построение и использование примера

Дополнительные сведения о компиляции и использовании примеров пользовательских элементов управления см. в разделе Примеры связывания пользовательского серверного элемента управления.

См. также

Основные понятия

Пример составного веб-элемента управления

Пример управления состоянием настраиваемого свойства

Другие ресурсы

Разработка пользовательских серверных элементов управления ASP.NET