深入講解控件的屬性持久化(一)
系列文章連結: <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/06/1262109.html">ASP.NET自定義控件元件開發 第一章 待續</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/06/1262386.html">ASP.NET自定義控件元件開發 第一章 第二篇 接着待續</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/07/1262566.html">ASP.NET自定義控件元件開發 第一章 第三篇</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/08/1263998.html">ASP.NET自定義控件元件開發 第二章 繼承WebControl的自定義控件</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/11/1265466.html">ASP.NET自定義控件元件開發 第三章 為控件添加事件 前篇</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/12/1265602.html">ASP.NET自定義控件元件開發 第三章 為控件添加事件 後篇</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/24/1270387.html">ASP.NET自定義控件元件開發 第四章 組合控件開發CompositeControl</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/25/1275741.html">ASP.NET自定義控件元件開發 第四章 組合控件開發CompositeControl 後篇 --事件冒泡</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/08/28/1270388.html">ASP.NET自定義控件元件開發 第五章 模闆控件開發</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/10/15/1312071.html">ASP.NET2.0自定義控件元件開發 第六章 深入講解控件的屬性</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2008/10/21/1315734.html">ASP.NET2.0元件控件開發視訊 初體驗</a>
自從寫了控件開發的文章後,收到了不少朋友的來信,提出了不少的問題,感謝大家的關注。今天就把大家說的一些問
題來講解下。
雖然我這個系列是控件開發,但是我的目的還是希望大家通過開發控件更加快速的對ASP.NET有更加深入的了解,是以
我們也很有必要把一些基礎性的東西将清楚。
為了達到深入講解屬性的目的,我首先來講講頁面周期和頁面解析的一些問題:
1。頁面的解析:
大家可能聽說,頁面在送出給伺服器的時候,都是被解析成為了一個個的繼承與Page的類,最直接的證明就是:
Code
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
大家看看,就是那個代碼隐藏
CodeFile="Default.aspx.cs" Inherits="_Default"
大家也許覺得疑惑:一個aspx的頁面都是一些标記語言啊,如下面:(注意:是将下面的文本解析為一個類)
<!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>
<asp:Button ID="Button1" runat="server" Text="送出" OnClick="Button1_Click" /></div>
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</form>
</body>
</html>
大家也許看見了,上面的源是一個類似與XML的文檔。
當這個頁面發送到伺服器後,伺服器就開發用正則表達模式來解析這個文檔,比如,看見"<head>"就把他解析為一個
LiteralControl,如:LiteralControl head = new LiteralControl("<head>");,看見了<form>就解析為HtmlForm
類,就這樣,一個類似與XML的文檔就解析為了一個繼承于Page的cs類。如下:(僞碼,隻是示範而已,真正的不是這樣的):
public class Default_aspx :Page
{
//.,
HtmlForm form = new HtmlForm();
Button button1 = new Button();
buton1.Text="送出";
button1.Click+= Button1_Click(object sender, EventArgs e);
//
.
}
大家注意:頁面解析的時候,把我們為控件設定的值,如Text=“ 送出”都初始化給了控件。
然後,将解析完的類生成一個類的執行個體,之後就開始頁面的生命周期。
2.HTTP工作模式
HTTP是一種無狀态的連接配接模式,也就是說,用戶端像伺服器發送請求職後,伺服器響應後就不再維持用戶端的資訊。
3.綜合1,2講解屬性持久化
現在假設,在Button中沒有屬性持久化這個特點。我們看看下面的流程:
3.1:再頁面中放入一個Button按鈕,并且設定Text 屬性為“送出”,然後再Button的點選Click事件中寫下如下
代碼:
protected void Button1_Click(object sender, EventArgs e)
{
if (this.Button1.Text == "送出")
this.Button1.Text = "清空";
else
this.Button1.Text = "送出";
}
3.2:将頁面送出給伺服器,此時,就開始了頁面的解析工作,并且在解析的時候,使得Button的Text屬性設定為了
“送出”,然後就開始了頁面的生命周期。最後頁面就呈現在我們面前。
3.3:我們在浏覽器的頁面中點選Button按鈕,頁面就再次送出伺服器,頁面開始解析,然後開始生命周期,在周期的
某一個階段(以後講解),就會引發按鈕的Click事件,将按鈕的文本設定為”清空“,最後頁面呈現在我們面前。
3.4;當我們再次點選按鈕,我們本來是想使得按鈕顯示”送出“,但是不管我們點選多少次,按鈕總是顯示”清空“。
為什麼?
因為每次把頁面送出的時候,頁面解析的結果都是将Button的Text屬性設定為”送出“,第二次點選按鈕時,按鈕的
Text屬性顯示的是”清空“,但是一旦頁面送出後,頁面還時按照第一次那樣解析,并且初始化。按鈕的Click事件還是發現Button的Text為”送出“。因為上次送出後,按鈕的Text 屬性-”清空“,沒有儲存(基于Http協定)。
是以為了使得我們可以像 WinForm那樣開發,為了使得達到我們想要的效果。ASP.NET中就采用了”儲存狀态“技術.
4.儲存狀态技術
其實也很簡單,隻是每次在頁面回傳的過程中,把上次的頁面的所有設定的狀态儲存在一個表單字元串"_VIEWSTATE",中,具體是這樣的,當頁面回到用戶端的時候,伺服器就把頁面中的控件的狀态序列化為一個字元串,
一同發給用戶端,當用戶端送出頁面後,伺服器就對送出的_VIEWSTATE解析,進行反序列化,然後根據反序列化的結
果,恢複各個控件的狀态,這樣就得到到上次頁面的狀态。
然後在頁面的生命周期中,如果在控件的事件中有修改控件狀态的代碼,就在合适的時候引發,然後,再次更新_VIEWSTATE 的值。
這樣控件屬性的持久化就完成了。
是以我們在開發自定義控件的時候,常常要顯示的生命控件屬性的持久化。就是用ViewState.