Esempio di gestione dello stato delle proprietà personalizzate
Aggiornamento: novembre 2007
Nell'esempio riportato di seguito vengono illustrate le modalità di definizione di una proprietà del controllo server il cui tipo implementa la gestione dello stato. Il controllo BookNew nell'esempio definisce una proprietà Author il cui tipo StateManagedAuthor esegue la gestione dello stato implementando l'interfaccia IStateManager. Il tipo StateManagedAuthor è descritto in Esempio di gestione dello stato dei tipi personalizzati.
Il controllo BookNew in questa sezione è analogo al controllo Book descritto in Esempio di proprietà dei controlli server, che mostra come definire una proprietà con sottoproprietà. La differenza fra i controlli BookNew e Book consiste nel fatto che il tipo della proprietà Author in BookNew delega la gestione dello stato della proprietà Author ai metodi di gestione dello stato del tipo StateManagedAuthor della proprietà. Al contrario, il controllo Book gestisce esplicitamente lo stato della proprietà Author.
I metodi utilizzati per implementare la gestione dello stato, TrackViewState, SaveViewState e LoadViewState, sono descritti nella sezione "Illustrazione del codice" più avanti in questo argomento.
Listato di codice per il controllo BookNew
Listato di codice per il controllo BookNew. La gestione dello stato è eseguita dalla proprietà Author di BookNew e i metodi di gestione dello stato, ovvero TrackViewState, SaveViewState e LoadViewState, della 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
}
}
Illustrazione del codice
Il controllo BookNew illustra il modello per l'implementazione delle proprietà i cui tipi gestiscono lo stato implementando l'interfaccia IStateManager. Oltre a eseguire l'analisi del codice per il controllo BookNew in questa sezione, può essere utile esaminare anche il codice per il tipo StateManagedAuthor, ovvero il tipo della proprietà Author del controllo BookNew. Il listato di codice per StateManagedAuthor si trova nella sezione Esempio di gestione dello stato dei tipi personalizzati.
BookNew definisce la proprietà Author come di sola lettura e archiviata in un campo privato del tipo StateManagedAuthor. Nella funzione di accesso Author della proprietà, se il campo privato corrispondente alla proprietà è null, Nothing in Visual Basic, BookNew assegna un nuovo oggetto StateManagedAuthor al campo privato. Se BookNew ha avviato la gestione dello stato, BookNew avvia la gestione dello stato sul nuovo oggetto StateManagedAuthor generato chiamando il metodo TrackViewState dell'oggetto. Per ulteriori informazioni sulla gestione, vedere Esempio di proprietà dei controlli server.
La proprietà Author contribuisce alla gestione dello stato chiamando i metodi IStateManager dell'oggetto StateManagedAuthor dai relativi metodi di gestione dello stato:TrackViewState, SaveViewState e LoadViewState.
Il metodo TrackViewState, BookNew in cui è stato eseguito l'override chiama il metodo TrackViewState della classe base e il metodo TrackViewState dell'oggetto StateManagedAuthor che corrisponde alla proprietà Author.
Il metodo SaveViewState, BookNew in cui è stato eseguito l'override chiama il metodo SaveViewState della classe base e il metodo SaveViewState dell'oggetto StateManagedAuthor che corrisponde alla proprietà Author. Se la proprietà Author deve salvare lo stato, il metodo SaveViewState del controllo BookNew restituisce un oggetto Pair che contiene lo stato della classe base e della proprietà Author. Se la proprietà Author non deve salvare lo stato, il metodo restituisce solo lo stato in risposta alla chiamata SaveViewState alla classe base. In base al numero di proprietà personalizzate che contribuiscono allo stato, è necessario restituire gli oggetti di tipo Pair, Triplet, o Array da SaveViewState. In questo modo, è possibile recuperare più facilmente le varie parti dello stato salvato nel metodo LoadViewState. In tal caso si utilizza la classe Pair perché sono presenti due elementi: lo stato della classe base e lo stato Author.
Il metodo LoadViewState, BookNew in cui è stato eseguito l'override implementa l'inverso delle operazioni eseguite nel metodo LoadViewState. BookNew carica lo stato nella classe base e nella proprietà Author o se la proprietà Author non doveva salvare lo stato, BookNew carica lo stato solo nella classe base. È necessario chiamare sempre il metodo LoadViewState della classe base anche se lo stato salvato è null, Nothing in Visual Basic, perché la classe base potrebbe aver implementato altra logica in questo metodo se non deve ripristinare lo stato.
Pagina di prova per il controllo BookNew
L'esempio seguente viene illustrata una pagina ASPX che utilizza il controllo BookNew.
<%@ 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>
Generazione e utilizzo dell'esempio
Compilare il controllo BookNew con le classi StateManagedAuthor e StateManagedAuthorConverter descritte in Esempio di gestione dello stato dei tipi personalizzati.
Per informazioni sulla generazione e sull'utilizzo del controllo in una pagina, vedere Generazione degli esempi dei controlli server personalizzati.
Vedere anche
Concetti
Esempio di gestione dello stato dei tipi personalizzati
Esempio di proprietà dei controlli server