Sdílet prostřednictvím


Beispiel für die Zustandsverwaltung einer benutzerdefinierten Eigenschaft

Aktualisiert: November 2007

In diesem Beispiel wird veranschaulicht, wie eine Eigenschaft für ein Serversteuerelement definiert wird, deren Typ seine eigene Zustandsverwaltung implementiert. In diesem Beispiel definiert das BookNew-Steuerelement eine Author-Eigenschaft, deren Typ, StateManagedAuthor, durch Implementierung der IStateManager-Schnittstelle seine eigene Zustandsverwaltung durchführt. Der StateManagedAuthor-Typ wird in Beispiel für die Zustandsverwaltung eines benutzerdefinierten Formats beschrieben.

Das BookNew-Steuerelement in diesem Thema ist dem Book-Steuerelement ähnlich, das in Beispiel für die Eigenschaften eines Serversteuerelements beschrieben wird, das aufzeigt, wie eine Eigenschaft definiert wird, die über untergeordnete Eigenschaften verfügt. Der Unterschied zwischen dem BookNew -Steuerelement und dem Book-Steuerelement liegt darin, dass der Typ der Author-Eigenschaft in BookNew die Zustandsverwaltung der Author-Eigenschaft an die Zustandsverwaltungsmethoden des StateManagedAuthor-Typs der Eigenschaft delegiert. Im Gegensatz dazu verwaltet das Book-Steuerelement den Zustand seiner Author-Eigenschaft explizit.

Die Methoden, die zur Implementierung der Zustandsverwaltung verwendet werden (TrackViewState,SaveViewState und LoadViewState), werden im Abschnitt "Codeerläuterung" weiter unten in diesem Thema beschrieben.

Codeauflistung für das BookNew-Steuerelement

Im Folgenden finden Sie eine Codeauflistung des BookNew-Steuerelements. Die Zustandsverwaltung wird von der Author-Eigenschaft des BookNew-Steuerelements sowie von den Zustandsverwaltungsmethoden (TrackViewState, SaveViewState und LoadViewState) der StateManagedAuthor-Klasse durchgeführt.

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

    }
}

Codeerläuterung

Das BookNew-Steuerelement veranschaulicht das Muster für die Implementierung von Eigenschaften, deren Typen durch Implementieren der IStateManager-Schnittstelle ihren eigenen Zustand verwalten. Parallel zum Code für das BookNew-Steuerelement, den Sie in diesem Thema finden, sollten Sie sich auch den Code für den StateManagedAuthor-Typ anschauen. Dies ist der Typ der Author-Eigenschaft des BookNew-Steuerelements. Die Codeauflistung für StateManagedAuthor finden Sie im Thema Beispiel für die Zustandsverwaltung eines benutzerdefinierten Formats.

BookNew legt die Author-Eigenschaft als eine schreibgeschützte Eigenschaft fest, die in einem privaten Feld vom Typ StateManagedAuthor gespeichert wird. Wenn im Author-Eigenschaftenaccessor das private Feld, das der Eigenschaft entspricht, null (Nothing in Visual Basic) ist, weist BookNew dem privaten Feld ein neues StateManagedAuthor-Objekt zu. Nachdem BookNew die Verfolgung des Zustands gestartet hat, initiiert BookNew die Zustandsverfolgung auf dem neu erstellten StateManagedAuthor-Objekt, indem es die TrackViewState-Methode des Objekts aufruft. Weitere Informationen zum Thema Verfolgung finden Sie unter Beispiel für die Eigenschaften eines Serversteuerelements.

Die Author-Eigenschaft nimmt an der Zustandsverwaltung teil, indem sie aus den eigenen Zustandsverwaltungsmethoden heraus die IStateManager-Methoden des StateManagedAuthor-Objekts aufruft: TrackViewState, SaveViewState und LoadViewState.

In der überschriebenen TrackViewState-Methode ruft BookNew die TrackViewState-Methode der Basisklasse und die TrackViewState-Methode des StateManagedAuthor-Objekts auf, das der Author-Eigenschaft entspricht.

In der überschriebenen SaveViewState-Methode ruft BookNew die SaveViewState-Methode der Basisklasse und die SaveViewState-Methode des StateManagedAuthor-Objekts auf, das der Author-Eigenschaft entspricht. Wenn die Author-Eigenschaft Zustand zu speichern hat, gibt die SaveViewState-Methode des BookNew-Steuerelements ein Pair-Objekt zurück, das den Zustand der Basisklasse und der Author-Eigenschaft enthält. Wenn die Author-Eigenschaft keinen Zustand zu speichern hat, gibt die Methode nur den Zustand zurück, der von dem SaveViewState-Aufruf an die Basisklasse zurückgegeben wurde. Je nach Anzahl der benutzerdefinierten Eigenschaften, die zum Zustand beitragen, sollten Sie aus SaveViewState Objekte vom Typ Pair, Triplet oder Array zurückgeben. Dadurch können Sie in der LoadViewState-Methode die verschiedenen Teile des gespeicherten Zustands leichter abrufen. In diesem Fall wird die Pair-Klasse verwendet, weil es zwei Elemente gibt, und zwar den Zustand der Basisklasse und den Author-Zustand.

In der überschriebenen LoadViewState-Methode implementiert BookNew die Umkehrung der Operationen, die in der LoadViewState-Methode implementiert sind. BookNew lädt den Zustand in die Basisklasse und in die Author-Eigenschaft. Wenn die Author-Eigenschaft jedoch keinen Zustand zu speichern hatte, lädt BookNew den Zustand nur in die Basisklasse. Sie sollten die LoadViewState-Methode der Basisklasse immer aufrufen, selbst wenn der gespeicherte Zustand null (Nothing in Visual Basic) ist – denn die Basisklasse hat in dieser Methode möglicherweise eine andere Logik implementiert, wenn sie keinen Zustand zum Wiederherstellen hat.

Testseite für das BookNew-Steuerelement

Das folgende Beispiel zeigt eine ASPX-Seite, die das BookNew-Steuerelement verwendet.

<%@ Page Language="C#"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
  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" runat="server">
    <title>
      BookNew test page
    </title>
  </head>
  <body>
    <form id="Form1" runat="server">
      <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>

Erstellen und Verwenden des Beispiels

Kompilieren Sie das BookNew-Steuerelement mit der StateManagedAuthor-Klasse und der in Beispiel für die Zustandsverwaltung eines benutzerdefinierten Formats beschriebenen StateManagedAuthorConverter-Klasse.

Weitere Informationen darüber, wie das Steuerelement erstellt und in einer Seite verwendet wird, finden Sie unter Erstellen der Beispiele für benutzerdefinierte Serversteuerelemente.

Siehe auch

Konzepte

Beispiel für die Zustandsverwaltung eines benutzerdefinierten Formats

Beispiel für die Eigenschaften eines Serversteuerelements

Weitere Ressourcen

Entwickeln von benutzerdefinierten ASP.NET-Serversteuerelementen