Condividi tramite


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("&nbsp")
            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("&nbsp;");
            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

Altre risorse

Sviluppo di controlli server ASP.NET personalizzati