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(" ")
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
}
}
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