Exemplo de Gerenciamento de Estado de Propriedade Personalizada
Este exemplo mostra como definir uma propriedade de controle de servidor cujo tipo implementa seu próprio gerenciamento de estado.O controle BookNew no exemplo define uma propriedade Author cujo tipo, StateManagedAuthor, executa seu próprio gerenciamento de estado pela implementação da interface IStateManager.O tipo StateManagedAuthor está descrito em Custom Type State Management Example.
O controle BookNew neste tópico é semelhante ao controle Book descrito em Exemplo das propriedades de controle do servidor, que mostra como definir uma propriedade que tem subpropriedades.A diferença entre os controles BookNew e Book é que o tipo da propriedade Author em BookNew delega o gerenciamento da propriedade Author para os métodos de gerenciamento do tipo de propriedade StateManagedAuthor.Em contraste, o controle Book explicitamente gerencia o estado de sua propriedade Author.
Os métodos usados para implementar o gerenciamento de estado (TrackViewState, SaveViewState e LoadViewState) são descritos mais tarde na seção "Discussão de Código" neste tópico.
Listagem de Código para o Controle BookNew
A listagem de código a seguir do controle BookNew.O gerenciamento de estado é executado pela propriedade Author de BookNew e o os métodos de gerenciamento de estado (TrackViewState, SaveViewState e LoadViewState) da classe StateManagedAuthor.
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}:BookNew runat=""server""> </{0}:BookNew>") _
> _
Public Class BookNew
Inherits WebControl
Private authorValue As StateManagedAuthor
< _
Bindable(True), _
Category("Appearance"), _
DefaultValue(""), _
Description("The name of the author."), _
DesignerSerializationVisibility( _
DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty) _
> _
Public Overridable ReadOnly Property Author() _
As StateManagedAuthor
Get
If authorValue Is Nothing Then
authorValue = New StateManagedAuthor
If IsTrackingViewState Then
CType(authorValue, IStateManager).TrackViewState()
End If
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 Render(ByVal writer As HtmlTextWriter)
MyBase.AddAttributesToRender(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()
End Sub
#Region "state management"
Protected Overrides Sub LoadViewState( _
ByVal savedState As Object)
Dim p As Pair = TryCast(savedState, Pair)
If p IsNot Nothing Then
MyBase.LoadViewState(p.First)
CType(Author, IStateManager).LoadViewState(p.Second)
Return
End If
MyBase.LoadViewState(savedState)
End Sub
Protected Overrides Function SaveViewState() As Object
Dim baseState As Object = MyBase.SaveViewState
Dim thisState As Object = Nothing
If authorValue IsNot Nothing Then
thisState = _
CType(authorValue, IStateManager).SaveViewState()
End If
If thisState IsNot Nothing Then
Return New Pair(baseState, thisState)
Else
Return baseState
End If
End Function
Protected Overrides Sub TrackViewState()
If authorValue IsNot Nothing Then
CType(Author, IStateManager).TrackViewState()
End If
MyBase.TrackViewState()
End Sub
#End Region
End Class
End Namespace
// BookNew.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}:BookNew runat=\"server\"> </{0}:BookNew>")
]
public class BookNew : WebControl
{
private StateManagedAuthor authorValue;
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The name of the author."),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty)
]
public virtual StateManagedAuthor Author
{
get
{
if (authorValue == null)
{
authorValue = new StateManagedAuthor();
if (IsTrackingViewState)
{
((IStateManager)authorValue).TrackViewState();
}
}
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 Render(HtmlTextWriter writer)
{
base.AddAttributesToRender(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();
}
#region state management
protected override void LoadViewState(object savedState)
{
Pair p = savedState as Pair;
if (p != null)
{
base.LoadViewState(p.First);
((IStateManager)Author).LoadViewState(p.Second);
return;
}
base.LoadViewState(savedState);
}
protected override object SaveViewState()
{
object baseState = base.SaveViewState();
object thisState = null;
if (authorValue != null)
{
thisState = ((IStateManager)authorValue).SaveViewState();
}
if (thisState != null)
{
return new Pair(baseState, thisState);
}
else
{
return baseState;
}
}
protected override void TrackViewState()
{
if (authorValue != null)
{
((IStateManager)authorValue).TrackViewState();
}
base.TrackViewState();
}
#endregion
}
}
Discussão de Código
O controle BookNew demonstra o padrão de implementação de propriedades cujos tipos gerenciam seu próprio estado pela implementação da interface IStateManager.Enquantto examina o código do controle BookNew neste tópico, você pode achá-lo útil também para examinar o código do tipo StateManagedAuthor, o tipo da propriedade Author do controle BookNew.A listagem de código para StateManagedAuthor está no tópico Custom Type State Management Example.
BookNew define a propriedade Author como uma propriedade de leitura somente, armazenada no campo privado de tipo StateManagedAuthor.No acessador de propriedade Author, se o campo privado correspondente à propriedade é null (Nothing em Visual Basic), BookNew atribui um novo objeto StateManagedAuthor ao campo privado.Se BookNew iniciou o estado de acompanhamento, BookNew inicia o estado de acompanhamento no objeto criado mais novo StateManagedAuthor invocando o método TrackViewState do objeto.Para obter mais informações, consulte Exemplo das propriedades de controle do servidor.
The Author propriedade participa de gerenciamento de estado, chamando o IStateManager métodos para o StateManagedAuthor objeto a partir de seus próprios métodos de gerenciamento de estado: TrackViewState, SaveViewState, e LoadViewState.
No método TrackViewState substituído, BookNew chama o método TrackViewState da classe base e o método TrackViewState do objeto StateManagedAuthor que corresponde à propriedade Author.
No método SaveViewState substituído, BookNew invoca o método SaveViewState da classe base e o método SaveViewState do objeto StateManagedAuthor que corresponde à propriedade Author.Se a propriedade Author tem estado para salvar, o método SaveViewState do controle BookNew retorna um objeto Pair que contém o estado da classe base e da propriedade Author.Se a propriedade Author não tem estado para salvar, o método retorna apenas o estado retornado pela chamada SaveViewState à classe base.Baseado no número de propriedades personalizadas que colaboram no estado, você deve retornar objetos do tipo Pair, Triplet ou Array de SaveViewState.Isso permite que você recupere as diferentes partes do estado salvo mais facilmente no método LoadViewState.Neste caso, a classe Pair é usada, porque existem dois itens, o estado da classe base e o estado Author.
No substituído LoadViewState método, BookNew implementa o inverso das operações que ele implementados na LoadViewState método. BookNew carrega o estado para a classe base e para o Author propriedade, ou então, se a Author propriedade não tem estado para salvar, BookNew estado cargas em somente a classe base. Você sempre deve chamar o método LoadViewState da classe base, mesmo se o estado salvo estiver null (Nothing em Visual Basic), porque a classe base pode ter outra lógica aplicada a este método caso não tenha estado para restaurar.
Página Teste para o Controle BookNew
The following example shows an .aspx page that uses the BookNew control.
<%@ 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 Button_Click(object sender, EventArgs e)
{
BookNew1.Author.FirstName = "Bob";
BookNew1.Author.LastName = "Kelly";
BookNew1.Title = "Contoso Stories";
BookNew1.Price = 39.95M;
Button1.Visible = false;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" >
<title>
BookNew test page
</title>
</head>
<body>
<form id="Form1" >
<aspSample:BookNew ID="BookNew1" Runat="server"
BorderStyle="Solid" BorderWidth="1px" Title="Tailspin Stories"
CurrencySymbol="$" BackColor="#FFE0C0" Font-Names="Tahoma"
Price="16" BookType="Fiction">
<Author FirstName="Judy" LastName="Lew" />
</aspSample:BookNew>
<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="BookNewTest.aspx"
Runat="server">
Reload Page</asp:HyperLink>
</form>
</body>
</html>
Construindo e Usando o Exemplo
Compile o controle BookNew com a classe StateManagedAuthor e a classe StateManagedAuthorConverter descrita em Custom Type State Management Example.
Para mais informações a respeito da construção do controle e uso dele em uma página, veja Construindo os Exemplos de Controle de Servidor Personalizado.
Consulte também
Conceitos
Custom Type State Management Example
Exemplo das propriedades de controle do servidor