Beispiel für den Vergleich zwischen Steuerelementzustand und Ansichtszustand
Aktualisiert: November 2007
Dieses Beispiel zeigt, wie Sie ein benutzerdefiniertes Steuerelement mit dem Namen IndexButton erstellen, das mithilfe des Steuerelementzustands wichtige Zustandsinformationen über mehrere Seitenanforderungen hinweg speichert. Zwar ähnelt der in ASP.NET 2.0 eingeführte Steuerelementzustand dem Ansichtszustand, in funktioneller Hinsicht ist er jedoch vom Ansichtszustand unabhängig. Der Ansichtszustand kann vom Seitenentwickler für eine Seite oder für ein einzelnes Steuerelement aus Leistungsgründen deaktiviert werden. Dies trifft für den Steuerelementzustand jedoch nicht zu. Der Steuerelementzustand wurde zum Speichern wichtiger Steuerelementdaten (z. B. die Seitennummer eines Pagersteuerelements) entwickelt, die für ein Postback zur Verfügung stehen müssen, damit das Steuerelement auch bei deaktiviertem Ansichtszustand funktioniert. Standardmäßig speichert das ASP.NET-Seitenframework den Steuerelementzustand im gleichen ausgeblendeten Element der Seite, in dem auch der Ansichtszustand gespeichert wird. Selbst bei deaktiviertem Ansichtszustand oder wenn der Zustand mit Session verwaltet wird, findet eine Übermittlung des Steuerelementzustands an den Client und wieder zurück zum Server statt. Beim Postback deserialisiert ASP.NET den Inhalt des ausgeblendeten Elements und lädt den Steuerelementzustand in jedes Steuerelement, das für den Steuerelementzustand registriert ist.
Hinweis: |
---|
Verwenden Sie den Steuerelementzustand nur für geringe Mengen wichtiger Daten, die für das Steuerelement über mehrere Postbacks hinweg eine entscheidende Rolle spielen. Verwenden Sie den Steuerelementzustand nicht als Ersatz für den Ansichtszustand. |
Das Beispiel zeigt ein benutzerdefiniertes Steuerelement, das den Zustand sowohl im Steuerelementzustand als auch im Ansichtszustand speichert. Im Beispiel leitet sich das IndexButton-Steuerelement von der Button-Klasse ab. Es definiert eine Index-Eigenschaft, die im Steuerelementzustand gespeichert wird. Zum Vergleich: IndexButton definiert auch eine IndexInViewState-Eigenschaft, die aber im ViewState-Wörterbuch gespeichert wird. Um den Unterschied zwischen Steuerelementzustand und Ansichtszustand zu verstehen, verwenden Sie das IndexButton-Steuerelement wie in der ASPX-Seite veranschaulicht, die im Abschnitt "Testseite für das IndexButton-Steuerelement" weiter unten in diesem Thema aufgeführt wird.
Codeauflistung für das IndexButton-Steuerelement
' IndexButton.vb
Option Strict On
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), _
ToolboxData("<{0}:IndexButton runat=""server""> </{0}:IndexButton>") _
> _
Public Class IndexButton
Inherits Button
Private indexValue As Integer
< _
Bindable(True), _
Category("Behavior"), _
DefaultValue(0), _
Description("The index stored in control state.") _
> _
Public Property Index() As Integer
Get
Return indexValue
End Get
Set(ByVal value As Integer)
indexValue = value
End Set
End Property
< _
Bindable(True), _
Category("Behavior"), _
DefaultValue(0), _
Description("The index stored in view state.") _
> _
Public Property IndexInViewState() As Integer
Get
Dim obj As Object = ViewState("IndexInViewState")
If obj Is Nothing Then obj = 0
Return CInt(obj)
End Get
Set(ByVal value As Integer)
ViewState("IndexInViewState") = value
End Set
End Property
Protected Overrides Sub OnInit(ByVal e As EventArgs)
MyBase.OnInit(e)
Page.RegisterRequiresControlState(Me)
End Sub
Protected Overrides Function SaveControlState() As Object
' Invoke the base class's method and
' get the contribution to control state
' from the base class.
' If the indexValue field is not zero
' and the base class's control state is not null,
' use Pair as a convenient data structure
' to efficiently save
' (and restore in LoadControlState)
' the two-part control state
' and restore it in LoadControlState.
Dim obj As Object = MyBase.SaveControlState()
If indexValue <> 0 Then
If obj IsNot Nothing Then
Return New Pair(obj, indexValue)
Else
Return indexValue
End If
Else
Return obj
End If
End Function
Protected Overrides Sub LoadControlState(ByVal state As Object)
If (state IsNot Nothing) Then
Dim p As Pair = TryCast(state, Pair)
If p IsNot Nothing Then
MyBase.LoadControlState(p.First)
indexValue = CInt(p.Second)
Else
If (TypeOf (state) Is Integer) Then
indexValue = CInt(state)
Else
MyBase.LoadControlState(state)
End If
End If
End If
End Sub
End Class
End Namespace
// IndexButton.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),
ToolboxData("<{0}:IndexButton runat=\"server\"> </{0}:IndexButton>")
]
public class IndexButton : Button
{
private int indexValue;
[
Bindable(true),
Category("Behavior"),
DefaultValue(0),
Description("The index stored in control state.")
]
public int Index
{
get
{
return indexValue;
}
set
{
indexValue = value;
}
}
[
Bindable(true),
Category("Behavior"),
DefaultValue(0),
Description("The index stored in view state.")
]
public int IndexInViewState
{
get
{
object obj = ViewState["IndexInViewState"];
return (obj == null) ? 0 : (int)obj;
}
set
{
ViewState["IndexInViewState"] = value;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override object SaveControlState()
{
// Invoke the base class's method and
// get the contribution to control state
// from the base class.
// If the indexValue field is not zero
// and the base class's control state is not null,
// use Pair as a convenient data structure
// to efficiently save
// (and restore in LoadControlState)
// the two-part control state
// and restore it in LoadControlState.
object obj = base.SaveControlState();
if (indexValue != 0)
{
if (obj != null)
{
return new Pair(obj, indexValue);
}
else
{
return (indexValue);
}
}
else
{
return obj;
}
}
protected override void LoadControlState(object state)
{
if (state != null)
{
Pair p = state as Pair;
if (p != null)
{
base.LoadControlState(p.First);
indexValue = (int)p.Second;
}
else
{
if (state is int)
{
indexValue = (int)state;
}
else
{
base.LoadControlState(state);
}
}
}
}
}
}
Codeerläuterung
Die Implementierung des IndexButton-Steuerelements zeigt die drei Schritte, die zum Aktivieren eines Steuerelements für die Teilnahme am Steuerelementzustand erforderlich sind:
Überschreiben der OnInit-Methode und Aufrufen der RegisterRequiresControlState-Methode, um die Seite für die Teilnahme am Steuerelementzustand zu registrieren. Dies muss bei jeder Anforderung geschehen.
Überschreiben der SaveControlState-Methode, um Daten im Steuerelementzustand zu speichern.
Überschreiben der LoadControlState-Methode, um Daten aus dem Steuerelementzustand zu laden. Diese Methode ruft die Basisklassenmethode auf und ruft den Beitrag der Basisklasse zum Steuerelementzustand ab. Wenn das indexValue-Feld nicht 0 und der Steuerelementzustand der Basisklasse nicht NULL ist, wird die Pair-Klasse als Datenstruktur verwendet, um den zweiteiligen Steuerelementzustand zu speichern und wiederherzustellen.
Testseite für das IndexButton-Steuerelement
Das folgende Beispiel zeigt eine Seite, die den Ansichtszustand deaktiviert, indem sie in der @ Page-Direktive das EnableViewState-Attribut auf false festlegt. Die Seite verwendet das IndexButton-Steuerelement und erhöht den Wert der Index-Eigenschaft und den Wert der IndexInViewState-Eigenschaft des Steuerelements im Page_Load-Ereignishandler um jeweils 1. Die Bezeichnungen in der Seitenanzeige stellen die Werte der Index-Eigenschaft und der IndexInViewState-Eigenschaft dar.
Da die Index-Eigenschaft im nicht deaktivierbaren Steuerelementzustand gespeichert wird, behält die Index-Eigenschaft bei einem Postback ihren Wert bei und wird jedes Mal um 1 erhöht, wenn die Seite zurück an den Server gesendet wird. Im Unterschied dazu ist der Standardwert der IndexInViewState-Eigenschaft immer 0, da die IndexInViewState-Eigenschaft im (für die Seite deaktivierten) Ansichtszustand gespeichert ist.
<%@ Page Language="VB" Trace="true" EnableViewState="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Label1.Text = IndexButton1.Index.ToString()
Label2.Text = IndexButton1.IndexInViewState.ToString()
IndexButton1.Index += 1
IndexButton1.IndexInViewState += 1
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>IndexButton test page</title>
</head>
<body>
<form id="form1" runat="server">
Click the button:
<aspSample:IndexButton Text="IndexButton"
ID="IndexButton1" runat="server"/>
<br />
<br />
The value of the Index property of IndexButton is:<br />
<asp:Label ID="Label1" Runat="server" Text="Label">
</asp:Label>
<br />
<br />
The value of the IndexInViewState property of IndexButton is:
<br />
<asp:Label ID="Label2" Runat="server" Text="Label">
</asp:Label>
<br />
</form>
</body>
</html>
<%@ Page Language="C#" Trace="true" EnableViewState="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
Label1.Text = (IndexButton1.Index++).ToString();
Label2.Text = (IndexButton1.IndexInViewState++).ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>IndexButton test page</title>
</head>
<body>
<form id="form1" runat="server">
Click the button:
<aspSample:IndexButton Text="IndexButton"
ID="IndexButton1" runat="server"/>
<br />
<br />
The value of the Index property of IndexButton is:<br />
<asp:Label ID="Label1" Runat="server" Text="Label">
</asp:Label>
<br />
<br />
The value of the IndexInViewState property of IndexButton is:
<br />
<asp:Label ID="Label2" Runat="server" Text="Label">
</asp:Label>
<br />
</form>
</body>
</html>
Erstellen und Verwenden des Beispiels
Weitere Informationen über das Kompilieren und Verwenden der benutzerdefinierten Beispielsteuerelemente finden Sie unter Erstellen der Beispiele für benutzerdefinierte Serversteuerelemente.
Siehe auch
Konzepte
Übersicht über den ASP.NET-Ansichtszustand
Empfehlungen zur ASP.NET-Zustandsverwaltung
Weitere Ressourcen
Entwickeln von benutzerdefinierten ASP.NET-Serversteuerelementen