Partilhar via


Exemplo das propriedades de controle do servidor

Este exemplo mostra como criar um controle chamado Book que persiste propriedades simples e que tenham subpropriedades.

Uma propriedade simples é uma propriedade cujo tipo é uma sequência de caracteres ou um tipo que mapeia facilmente para uma sequência de caracteres.Uma propriedade simples é persistida como um atributo na marca de abertura do controle sem qualquer trabalho de sua parte.Propriedades do tipo String e tipos de valor primitivos na biblioteca de classes do .NET Framework, como Boolean, Int16, Int32, e Enum são propriedades simples.Você pode adicionar código para armazenar uma propriedade simples no dicionário ViewState para o gerenciamento de estado em postagens.

Refere-se a uma propriedade como complexa quando o tipo dela é uma classe que tem propriedades, as quais são chamadas subpropriedades.Por exemplo, o tipo do Font propriedade de WebControl é o FontInfo a própria classe possui propriedades sistema autônomo Bold e Name. Bold e Name são subproperties das Font propriedade de WebControl. O framework de página do ASP.NET pode persistir subpropriedades na marca de abertura de um controle usando sintaxe hifenizada (por exemplo, Font-Bold="true"), mas subpropriedades são mais legíveis na página quando persistidas dentro das marcas do controle (por exemplo, <font Bold="true">).

Para ativar um designer visual para persistir subpropriedades como filhos do controle, você deve aplicar vários atributos de tempo de design para a propriedade e seu tipo; a persistência padrão é atributos hifenizados na marca do controle.Além disso, uma propriedade que tenha subpropriedades também precisa de gerenciamento de estado personalizado para usar estado de exibição, conforme descrito na seção "Discussão de Código" mais adiante neste tópico.

O controle Book definido no exemplo é um controle que pode ser usado em um página da Web para exibir informações sobre um livro em um catálogo.O controle Book define as propriedades a seguir:

  • Author, uma propriedade com subpropriedades cujo tipo é o tipo personalizado Author.O tipo Author tem suas próprias propriedades, como FirstName e LastName, que são subpropriedades da propriedade Author.

  • BookType, uma propriedade simples cujo tipo seja a enumeração personalizada BookType.A enumeração BookType tem valores como Fiction e NonFiction.

  • CurrencySymbol, uma propriedade simples cujo tipo é o tipo interno String.

  • Price, uma propriedade simples cujo tipo é o tipo interno Decimal.

  • Title, uma propriedade simples cujo tipo é o tipo interno String.

As propriedades BookType, CurrencySymbol, Price e Title são todas as propriedades simples e, portanto, não precisam de quaisquer atributos especiais para persistência de página.A estrutura de página persiste essas propriedades por padrão como atributos na marca do controle, como no exemplo a seguir:

<aspSample:Book Title="Wingtip Toys Stories" 
  CurrencySymbol="$" 
  Price="16" 
  BookType="Fiction">
</aspSample:Book>

A propriedade Author e as propriedades da classe Author precisam de atributos em tempo de design para habilitar a persistência dentro das marcas do controle, como mostrado no exemplo o seguir:

<aspSample:Book >
  <Author FirstName="Judy" LastName="Lew" />
</aspSample:Book>

O controle Book armazena suas propriedades simples no dicionário ViewState.No entanto, o controle Book tem que implementar o gerenciamento de estado personalizado para a propriedade Author para gerenciar o estado da propriedade em postagens.

Uma implementação de qualidade de produção do controle Book pode definir propriedades para outros dados relacionados à reserva, como as datas do aplicativo e da publicação.Além disso, a propriedade Author pode ser substituída por uma propriedade de coleção.Para obter informações sobre como implementar uma propriedade de coleção, consulte Exemplo da propriedade de coleção do controle da Web.

Observação:

Um desenvolvedor de página pode desativar o estado de exibição para uma página ou para controles individuais na página.Se o seu controle precisa manter o estado crítico em postagens para seu funcionamento interno, você pode usar o mecanismo de estado de controle definido em ASP.NET 2.0.Estado do controle é descrito em Exemplo de Estado de Controle versus Estado de Exibição.

Listagem de Código para o Controle Book

' Book.vb
Option Strict On
Imports System
Imports System.ComponentModel
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), _
    DefaultProperty("Title"), _
    ToolboxData("<{0}:Book runat=""server""> </{0}:Book>") _
    > _
    Public Class Book
        Inherits WebControl
        Private authorValue As Author
        Private initialAuthorString As String

        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue(""), _
        Description("The name of the author."), _
        DesignerSerializationVisibility( _
            DesignerSerializationVisibility.Content), _
        PersistenceMode(PersistenceMode.InnerProperty) _
        > _
        Public Overridable ReadOnly Property Author() As Author
            Get
                If (authorValue Is Nothing) Then
                    authorValue = New Author()
                End If
                Return authorValue
            End Get
        End Property

        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue(BookType.NotDefined), _
        Description("Fiction or Not") _
        > _
        Public Overridable Property BookType() As BookType
            Get
                Dim t As Object = ViewState("BookType")
                If t Is Nothing Then t = BookType.NotDefined
                Return CType(t, BookType)
            End Get
            Set(ByVal value As BookType)
                ViewState("BookType") = value
            End Set
        End Property

        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue(""), _
        Description("The symbol for the currency."), _
        Localizable(True) _
        > _
        Public Overridable Property CurrencySymbol() As String
            Get
                Dim s As String = CStr(ViewState("CurrencySymbol"))
                If s Is Nothing Then s = String.Empty
                Return s
            End Get
            Set(ByVal value As String)
                ViewState("CurrencySymbol") = value
            End Set
        End Property

        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue("0.00"), _
        Description("The price of the book."), _
        Localizable(True) _
        > _
        Public Overridable Property Price() As Decimal
            Get
                Dim p As Object = ViewState("Price")
                If p Is Nothing Then p = Decimal.Zero
                Return CType(p, Decimal)
            End Get
            Set(ByVal value As Decimal)
                ViewState("Price") = value
            End Set
        End Property

        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue(""), _
        Description("The title of the book."), _
        Localizable(True) _
        > _
        Public Overridable Property Title() As String
            Get
                Dim s As String = CStr(ViewState("Title"))
                If s Is Nothing Then s = String.Empty
                Return s
            End Get
            Set(ByVal value As String)
                ViewState("Title") = value
            End Set
        End Property

        Protected Overrides Sub RenderContents( _
            ByVal writer As HtmlTextWriter)
            writer.RenderBeginTag(HtmlTextWriterTag.Table)

            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.WriteEncodedText(Title)
            writer.RenderEndTag()
            writer.RenderEndTag()

            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.WriteEncodedText(Author.ToString())
            writer.RenderEndTag()
            writer.RenderEndTag()

            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.WriteEncodedText(BookType.ToString())
            writer.RenderEndTag()
            writer.RenderEndTag()

            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.Write(CurrencySymbol)
            writer.Write("&nbsp")
            writer.Write(String.Format("{0:F2}", Price))
            writer.RenderEndTag()
            writer.RenderEndTag()

            writer.RenderEndTag()
        End Sub

        Protected Overrides Sub LoadViewState( _
            ByVal savedState As Object)
            MyBase.LoadViewState(savedState)
            Dim auth As Author = CType(ViewState("Author"), Author)
            If auth IsNot Nothing Then
                authorValue = auth
            End If
        End Sub

        Protected Overrides Function SaveViewState() As Object
            If authorValue IsNot Nothing Then
                Dim currentAuthorString As String = _
                    authorValue.ToString()
                If Not _
                    (currentAuthorString.Equals(initialAuthorString)) Then
                    ViewState("Author") = authorValue
                End If
            End If
            Return MyBase.SaveViewState()
        End Function

        Protected Overrides Sub TrackViewState()
            If authorValue IsNot Nothing Then
                initialAuthorString = authorValue.ToString()
            End If
            MyBase.TrackViewState()
        End Sub

    End Class
End Namespace
// Book.cs
using System;
using System.ComponentModel;
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),
    DefaultProperty("Title"),
    ToolboxData("<{0}:Book runat=\"server\"> </{0}:Book>")
    ]
    public class Book : WebControl
    {
        private Author authorValue;
        private String initialAuthorString;

        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The name of the author."),
        DesignerSerializationVisibility(
            DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public virtual Author Author
        {
            get
            {
                if (authorValue == null)
                {
                    authorValue = new Author();
                }
                return authorValue;
            }

        }

        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(BookType.NotDefined),
        Description("Fiction or Not"),
        ]
        public virtual BookType BookType
        {
            get
            {
                object t = ViewState["BookType"];
                return (t == null) ? BookType.NotDefined : (BookType)t;
            }
            set
            {
                ViewState["BookType"] = value;
            }
        }

        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The symbol for the currency."),
        Localizable(true)
        ]
        public virtual string CurrencySymbol
        {
            get
            {
                string s = (string)ViewState["CurrencySymbol"];
                return (s == null) ? String.Empty : s;
            }
            set
            {
                ViewState["CurrencySymbol"] = value;
            }
        }


        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue("0.00"),
        Description("The price of the book."),
        Localizable(true)
        ]
        public virtual Decimal Price
        {
            get
            {
                object price = ViewState["Price"];
                return (price  == null) ? Decimal.Zero : (Decimal)price;
            }
            set
            {
                ViewState["Price"] = value;
            }
        }

        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The title of the book."),
        Localizable(true)
        ]
        public virtual string Title
        {
            get
            {
                string s = (string)ViewState["Title"];
                return (s == null) ? String.Empty : s;
            }
            set
            {
                ViewState["Title"] = value;
            }
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.RenderBeginTag(HtmlTextWriterTag.Table);

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            writer.WriteEncodedText(Title);
            writer.RenderEndTag();
            writer.RenderEndTag();

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            writer.WriteEncodedText(Author.ToString());
            writer.RenderEndTag();
            writer.RenderEndTag();

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            writer.WriteEncodedText(BookType.ToString());
            writer.RenderEndTag();
            writer.RenderEndTag();

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            writer.Write(CurrencySymbol);
            writer.Write("&nbsp;");
            writer.Write(String.Format("{0:F2}", Price));
            writer.RenderEndTag();
            writer.RenderEndTag();

            writer.RenderEndTag();
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);

            Author auth = (Author)ViewState["Author"];
            if (auth != null)
            {
                authorValue = auth;
            }
        }

        protected override object SaveViewState()
        {
            if (authorValue != null)
            {
                String currentAuthorString = authorValue.ToString();
                if (!(currentAuthorString.Equals(initialAuthorString)))
                {
                    ViewState["Author"] = authorValue;
                }
            }

            return base.SaveViewState();
        }

        protected override void TrackViewState()
        {
            if (authorValue != null)
            {
                initialAuthorString = authorValue.ToString();
            }
            base.TrackViewState();
        }

    }
}

Discussão de Código

DesignerSerializationVisibilityAttribute e PersistenceModeAttribute aplicados à propriedade Author do controle Book são descritos em Exemplo da propriedade de coleção do controle da Web.Esses atributos são necessários para serializar e persistir as propriedades da classe Author.

O mecanismo de estado de exibição se refere à técnica que o ASP.NET usa para manter o estado em postagens.O mecanismo serializa o estado de uma página e sua árvore de controle em representações de sequências de caracteres no final do processamento da página e desserializa a sequência de caracteres em um postback.Por padrão, a página envia as sequências de caracteres para o navegador como campos ocultos.Para obter mais informações, consulte Visão Geral sobre o Gerenciamento de Estado do ASP.NET.

Para gerenciar o estado de uma propriedade simples, defina-a como uma propriedade de leitura/escrita que é armazenada na propriedade ViewState do controle.O controle Book define suas propriedades simples (BookType, CurrencySymbol, Price e Title) dessa maneira.O estado das propriedades que você armazena na propriedade ViewState é gerenciado para você sem qualquer trabalho de sua parte.

Para gerenciar uma propriedade que tenha subpropriedades, você pode definir a propriedade como somente leitura e escrever código para gerenciar o estado do objeto.Para fazer isso, você substitui os seguintes métodos:

O tipo da propriedade ViewState, StateBag, é um dicionário com gerenciamento de estado interno.A classe StateBag implementa a interface IStateManager, que define os métodos TrackViewState, SaveViewState e LoadViewState.The StateBag classe implementa esses métodos para iniciar o acompanhamento de alterações de propriedades de acompanhamento após a inicialização, salvar os itens que foram modificados no participante da solicitação de página e carregar estado salvo em itens na nova postagem. StateBag Controla itens por marcar um item conforme modificado se o item é definido após o OnInit método é executado para uma solicitação de página. Por exemplo, se qualquer código na página que será executado após a inicialização de página define a propriedade Title do controle Book, uma alteração será feita para ViewState["Title"].sistema autônomo uma conseqüência, o valor armazenado em "título"chave no ViewState está marcado sistema autônomo modificadas. Para obter mais informações, consulte Visão Geral do Ciclo de Vida da Página ASP.NET.

O controle Book define a propriedade Author como uma propriedade somente de leitura e implementa o gerenciamento de estado personalizado da seguinte maneira:

  • No método TrackViewState, o controle Book primeiro salva a propriedade Author inicial em uma sequência de caracteres e então inicia o rastreamento de estado, chamando o método TrackViewState da classe base.

  • No método SaveViewState, o controle Book determina se a propriedade Author foi alterada do seu valor inicial.Se a propriedade foi alterada, Book salvará a propriedade Author no dicionário de ViewState usando a chave "Autor".O controle Book, em seguida, chama o método SaveViewState da classe base.Porque o rastreamento de estado está rodando, o objeto Author salvo em ViewState é automaticamente marcado como modificado e salvo como parte do estado de exibição da classe base.

  • Em LoadViewState, o controle Book primeiro chama o método LoadViewState da classe base.Esta chamada restaura automaticamente o dicionário ViewState.O controle Book, em seguida, determina se o dicionário ViewState tem um item armazenado em "Autor".Nesse caso, o controle carrega o valor do estado de exibição na propriedade Author.

O tipo Author (definido na listagem de código que segue) tem um conversor de tipos personalizado para que uma instância Author possa ser armazenada em estado de exibição.O conversor de tipos converte uma instância Author em uma sequência de caracteres e vice-versa.Definir um conversor de tipos permite que as subpropriedades de Author sejam definidas em um designer visual.O conversor de tipos personalizado é descrito em Exemplo de Conversor de Tipo.Os tipos que você pode armazenar em estado de exibição são limitados pela classe LosFormatter que o ASP.NET usa para serialização do estado de exibição.Os tipos que são serializados mais eficientemente são String; tipos de valor primitivos na biblioteca de classe do .NET Framework, como Boolean, Int16, Int32, Enum, Pair, Triplet, Array, ArrayList e Hashtable; e quaisquer tipos que contenham qualquer um desses tipos primitivos.Além disso, você também pode armazenar no estado de exibição tipos personalizados que tenham conversores de tipo definidos para eles, como Pair, Triplet, Array, ArrayList e Hashtable.Ao definir serialização do estado de exibição para o seu controle, você deve converter os seus dados de controle a um desses tipos.Se você armazenar tipos em estado de exibição que não sejam compatíveis com o mecanismo de serialização do estado de exibição, o seu controle pode compilar, mas irá gerar um erro em tempo de execução.Finalmente, tipos serializados (ou seja, tipos que implementam a interface ISerializable ou são marcados com SerializableAttribute) podem ser armazenados em estado de exibição, mas a serialização para esses tipos é significativamente mais lenta que para tipos primitivos.

O objeto de estado contribuído por um controle para a serialização é o estado de exibição do controle.A propriedade ViewState de um controle é somente uma parte do estado de exibição de um controle — é a parte que participa automaticamente no mecanismo do estado de exibição sem qualquer trabalho de sua parte.A classe Control implementa a lógica para salvar e carregar os itens modificados no dicionário ViewState nos seus métodos SaveViewState e LoadViewState.A outra parte ou partes do estado de exibição são objetos adicionais que você (e a sua classe base do controle) salva em estado de exibição, substituindo o método SaveViewState.Quando você substitui os métodos SaveViewState e LoadViewState, você deve chamar os métodos correspondentes da classe base.

Listagem de código para a classe Author

Aplicar NotifyParentPropertyAttribute a FirstName, LastName, e as propriedades MiddleName e definir o argumento do construtor do atributo para true faz com que um designer visual propague e serialize alterações para essas propriedades nas suas propriedades pai (uma instância Author).

' Author.vb
Option Strict On
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Globalization
Imports System.Web.UI

Namespace Samples.AspNet.VB.Controls
    < _
    TypeConverter(GetType(AuthorConverter)) _
    > _
    Public Class Author
        Dim firstNameValue As String
        Dim lastNameValue As String
        Dim middleNameValue As String

        Public Sub New()
            Me.New(String.Empty, String.Empty, String.Empty)
        End Sub

        Public Sub New(ByVal firstname As String, _
            ByVal lastname As String)
            Me.New(firstname, String.Empty, lastname)
        End Sub

        Public Sub New(ByVal firstname As String, _
            ByVal middlename As String, ByVal lastname As String)
            firstNameValue = firstname
            middleNameValue = middlename
            lastNameValue = lastname
        End Sub

        < _
        Category("Behavior"), _
        DefaultValue(""), _
        Description("First name of author."), _
        NotifyParentProperty(True) _
        > _
        Public Overridable Property FirstName() As String
            Get
                Return firstNameValue
            End Get
            Set(ByVal value As String)
                firstNameValue = value
            End Set
        End Property


        < _
        Category("Behavior"), _
        DefaultValue(""), _
        Description("Last name of author."), _
        NotifyParentProperty(True) _
        > _
        Public Overridable Property LastName() As String
            Get
                Return lastNameValue
            End Get
            Set(ByVal value As String)
                lastNameValue = value
            End Set
        End Property

        < _
        Category("Behavior"), _
        DefaultValue(""), _
        Description("Middle name of author."), _
            NotifyParentProperty(True) _
        > _
        Public Overridable Property MiddleName() As String
            Get
                Return middleNameValue
            End Get
            Set(ByVal value As String)
                middleNameValue = value
            End Set
        End Property

        Public Overrides Function ToString() As String
            Return ToString(CultureInfo.InvariantCulture)
        End Function

        Public Overloads Function ToString( _
            ByVal culture As CultureInfo) As String
            Return TypeDescriptor.GetConverter( _
                Me.GetType()).ConvertToString(Nothing, culture, Me)
        End Function
    End Class
End Namespace
// Author.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Web.UI;

namespace Samples.AspNet.CS.Controls
{
    [
    TypeConverter(typeof(AuthorConverter))
    ]
    public class Author
    {
        private string firstnameValue;
        private string lastnameValue;
        private string middlenameValue;

        public Author()
            :
            this(String.Empty, String.Empty, String.Empty)
        {
        }

        public Author(string firstname, string lastname)
            :
            this(firstname, String.Empty, lastname)
        {
        }

        public Author(string firstname, 
                    string middlename, string lastname)
        {
            firstnameValue = firstname;
            middlenameValue = middlename;
            lastnameValue = lastname;
        }

        [
        Category("Behavior"),
        DefaultValue(""),
        Description("First name of author."),
        NotifyParentProperty(true),
        ]
        public virtual String FirstName
        {
            get
            {
                return firstnameValue;
            }
            set
            {
                firstnameValue = value;
            }
        }

        [
        Category("Behavior"),
        DefaultValue(""),
        Description("Last name of author."),
        NotifyParentProperty(true)
        ]
        public virtual String LastName
        {
            get
            {
                return lastnameValue;
            }
            set
            {
                lastnameValue = value;
            }
        }

        [
        Category("Behavior"),
        DefaultValue(""),
        Description("Middle name of author."),
        NotifyParentProperty(true)
        ]
        public virtual String MiddleName
        {
            get
            {
                return middlenameValue;
            }
            set
            {
                middlenameValue = value;
            }
        }

        public override string ToString()
        {
            return ToString(CultureInfo.InvariantCulture);
        }

        public string ToString(CultureInfo culture)
        {
            return TypeDescriptor.GetConverter(
                GetType()).ConvertToString(null, culture, this);
        }
    }
}

Listagem de código para a enumeração BookType

' BookType.vb
Option Strict On
Imports System

Namespace Samples.AspNet.VB.Controls
    Public Enum BookType
        NotDefined = 0
        Fiction = 1
        NonFiction = 2
    End Enum
End Namespace
// BookType.cs
using System;

namespace Samples.AspNet.CS.Controls
{
    public enum BookType
    {
        NotDefined = 0,
        Fiction = 1,
        NonFiction = 2
    }
}

Página Teste para o Controle Book

The following example shows an .aspx page that uses the Book control.

<%@ Page Language="C#" Debug="true" Trace="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
  void Button_Click(object sender, EventArgs e)
  {
    Book1.Author.FirstName = "Bob";
    Book1.Author.LastName = "Kelly";
    Book1.Title = "Contoso Stories";
    Book1.Price = 39.95M;
    Button1.Visible = false;
  }  
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head id="Head1" >
    <title>
      Book test page
    </title>
  </head>
  <body>
    <form id="Form1" >
      <aspSample:Book ID="Book1" Runat="server"  
        Title="Tailspin Toys Stories" CurrencySymbol="$" 
        BackColor="#FFE0C0" Font-Names="Tahoma" 
        Price="16" BookType="Fiction">
        <Author FirstName="Judy" LastName="Lew" />
      </aspSample:Book>
      <br />
      <asp:Button ID="Button1" OnClick="Button_Click" 
        Runat="server" Text="Change" />
      <asp:Button ID="Button2" Runat="server" Text="Refresh" />
      <br />
      <br />
      <asp:HyperLink ID="Hyperlink1" href="BookTest.aspx" 
        Runat="server">
        Reload Page</asp:HyperLink>
    </form>
  </body>
</html>

Construindo e Usando o Exemplo

Compile as classes nesse exemplo com a classe AuthorConverter listada em Exemplo de Conversor de Tipo.

Para obter informações sobre a compilação e uso dos exemplos de controles personalizados, consulte Construindo os Exemplos de Controle de Servidor Personalizado.

Consulte também

Conceitos

Tipos de valores no CTS (Common Type System)

Referência

IsPrimitive

Outros recursos

Desenvolvendo Controles Personalizados ASP.NET Server