自定义控件的构建(5)

在ASP.NET框架中支持在回传中保存值的有2种方式:视图状态和控件状态

视图状态

ASP.NET中几个对象属性与控件最为密切的,就是ViewState了。

这里对其做下说明,任何可序列化类的实例均可添加到视图状态中,但是实际上,如果添加到名为_ViewState的隐藏表单域变的太大,会影响页面执行效率。

下面定义的控件包含了Text和ViewStateText属性,只有后者使用视图状态,那么ViewStateText属性的值会在页面回传中保存。

namespace ViewStateControl
{  
    /// <summary>
    ///支持视图状态
    /// </summary>
    public class SupportViewStateControls : WebControl
    {
        public string Text
        {
            get;
            set;
        }
        public string ViewStateText
        {
            get
            {
                if (ViewState["ViewStateText"] == null)
                    return String.Empty;
                else
                    return (string)ViewState["ViewStateText"];
            }
            set
            {
                ViewState["ViewStateText"] = value;
            }
        }
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("Text:" + Text);
            writer.WriteBreak();
            writer.Write("ViewStateText:" + ViewStateText);
            writer.WriteBreak();
        }
}
    }

上面的代码中ViewStateText属性使用了Control类的ViewState集合在页面回传中保持并赋给ViewStateText属性的值。

在添加一个值到ViewState集合中时,其会自动填充至_VIEWSTATE隐藏表单域

Tip:因为视图状态在页面的InitComplete()后加载,在PreRenderComplete()后保存,也就是说不能在InitComplete()之前检索视图状态或者PreRenderComplete()后添加值至视图状态

控件状态

之所以在ASP.NET中引入控件概念,即使在视图状态被禁用时,仍可以用控件状态将信息保存在_VIEWSTATE隐藏表单域中

这句话很费解,举例来说明:一个GridView中包含了500条记录,为了改善性能,我们可以禁用视图状态,防止其将这些数据填充到_VIEWSTATE域里,

但是对于当前页数及选中的记录,我们仍希望GridView记住这些信息,这时就用到了控件状态。

namespace ViewStateControl
{   
    /// <summary>
    ///支持控件状态
    /// </summary>
    public class SupportControlStateControls : WebControl
    {
        public string ViewStateText
        {
            get
            {
                if (ViewState["ViewStateText"] == null)
                    return String.Empty;
                else
                    return (string)ViewState["ViewStateText"];
            }
            set
            {
                ViewState["ViewStateText"] = value;
            }
        }
        private string _controlStateText;
        public string ControlStateText
        {
            get 
            {
                return _controlStateText;
            }
             set
            {
                _controlStateText = value;
            }
        }
        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresControlState(this);
            base.OnInit(e);
        }
        protected override object SaveControlState()
        {
            return _controlStateText;
        }
        protected override void LoadControlState(object savedState)
        {
            _controlStateText = (string)savedState;
        }
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("ViewStateText:" +ViewStateText);
            writer.WriteBreak();
            writer.Write("ControlStateText:" + ViewStateText);
            writer.WriteBreak();
        }
 }       
    }

这个代码用ViewStateText表示视图状态,ControlStateText属性表示控件状态,在OnInit()中RegisterRequiresControlState方法被调用指定该控件需要利用控件状态。SaveControlState和LoadControlState事件负责保存加载控件状态。

运行

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestStateControl.aspx.cs" Inherits="TestViewStateControl" %>
<%@ Register TagPrefix="states" Namespace="ViewStateControl" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>   
    <states:SupportControlStateControls ID="SupportControlStateControls1" EnableViewState="false" runat="server" />
    <asp:Button ID="Button1" runat="server" Text="Button" />
    </div>
    </form>
</body>
</html>
后台代码:
 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {           
            SupportControlStateControls1.ViewStateText = "Hello";
            SupportControlStateControls1.ControlStateText = "Hello";
        }
    }
因为EnableViewState属性被关闭,所以单击按钮时,只有ControlStateText的属性值不会丢失

 

 

 

本文参考了《ASP.NET 3.5 揭秘(卷2)》

posted @ 2010-07-25 16:41  Ringgo.Yao  阅读(...)  评论(...编辑  收藏