65.9K
CodeProject 正在变化。 阅读更多。
Home

动态控件中的 ViewState

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (14投票s)

2009年4月22日

CPOL

2分钟阅读

viewsIcon

113298

downloadIcon

3092

处理动态控件时维护 ViewState

引言

在 .NET 环境中使用动态控件时,ViewState 一直是一个问题;很多时候我们找不到 ViewState,并且在使用 Update Panel 时,会出现很多提示无效视图状态的错误。

我们为什么要使用 ViewState?是的,我们需要在回发期间维护控件的状态。现在想想你在编写一个 Classic ASP 应用程序,还记得如何保留控件属性吗?如果记得,那很好,否则本文将让你了解如何使用 Classic ASP 代码来克服 viewstate。

Using the Code

你只需要编写几行代码就可以实现这一点。从介绍中,人们可能会了解如何做到这一点!

我们将使用一个控件来询问一个人的地址详细信息,我们通过单击 Place Holder 控件内的“添加更多”按钮来动态创建它们。我们将在用户控件中将 EnableViewState 设置为 false,因为我们不再需要维护动态控件的视图状态。

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ContactDetails.ascx.cs"

Inherits="UserControl_ContactDetails" EnableViewState="false" %> 

让我们将此控件加载到 aspx 页面的 PlaceHolder 中。以下方法将有助于动态加载控件。

/// <summary>
/// Load the contact control based on Viewstate key
/// </summary>
private void LoadContactControls()
{
    for (int i = 0; i < int.Parse(ViewState[VIEWSTATEKEY].ToString()); i++)
    {
        phContactDetails.Controls.Add(LoadControl("~/UserControl/ContactDetails.ascx"));
    }
}

这是一个简单的 LoadControl 语句,我们从 ViewState [它在 aspx 上而不是控件上] 获取需要在 phContactDetails 中添加的控件的数量。在 PageLoad 事件中,我们已经分配了页面首次加载时需要显示的控件数量

if (!Page.IsPostBack)
{
    //Set the number of default controls
    ViewState[VIEWSTATEKEY] = ViewState[VIEWSTATEKEY] == null ? 
					2 : ViewState[VIEWSTATEKEY];
    
    //Load the contact control based on Viewstate key
    LoadContactControls();
}

到目前为止一切顺利,但我们仍然没有 ViewState,现在让我们回到控件并编写一些很棒的 Classic ASP 代码来获取控件本身的状态。在我们继续之前;我们都知道,当任何控件或 .NET 页面被渲染时,它们总是有一个包含所有控件项的单个 Form,没有其他东西。因此,我们将使用相同的做法来获取控件值。让我们看看如何操作。

protected void Page_Load(object sender, EventArgs e)
{
    //Retain the state of controls
    txtAddress1.Text = Request.Form[txtAddress1.UniqueID];
    txtAddress2.Text = Request.Form[txtAddress2.UniqueID];
    txtCity.Text = Request.Form[txtCity.UniqueID];
    txtFirstName.Text = Request.Form[txtFirstName.UniqueID];
    txtLastName.Text = Request.Form[txtLastName.UniqueID];
    txtZip.Text = Request.Form[txtZip.UniqueID];
}

正如我刚才提到的,我们总是拥有包含所有子控件的 Request.Form,我们使用 Form item 集合和 UniqueID 控件来从 Form 集合中获取值。当一个控件被渲染时,我们可以使用 JavaScript 上的 ClientID 来识别它。它还生成 UniqueID,它是 Item 集合的键。让我们看一些屏幕截图,它们意识到代码工作正常。 :)

DefaultControls.JPG

图片#1:页面加载时的默认控件

FirstClick.JPG

图片#2:单击“添加更多”按钮后

SecondClick.JPG

图片#3:让我们再单击一次

是的,它有效!!!

结论

本文并没有告诉您停止使用 ViewState,但是我们应该在需要时使用 ViewState,并且在动态控件的情况下,我们可以避免 ViewState,并且仍然在回发之间获得状态。

历史

  • 2009 年 4 月 22 日:首次发布
© . All rights reserved.