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(" ")
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(" ");
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:
TrackViewState, para sinalizar o controle para iniciar o rastreamento de alterações de propriedade após a inicialização.
SaveViewState, para salvar a propriedade (se ela tiver sido alterada) no final da solicitação de página.
LoadViewState, para carregar o estado salvo na propriedade em um postback.
Observação: Existem outros métodos para gerenciar o estado de propriedade complexa em adição ao método abordado aqui.Você pode estender o método usado em Explicação Passo a Passo: Desenvolvendo e Usando um Controle de Servidor Personalizado modificando o estado de exibição com cada alteração de propriedade.Você também pode gerenciar o estado dentro da classe da propriedade, conforme mostrado em Exemplo de Gerenciamento de Estado de Propriedade Personalizada.
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)