例6-1代碼1:SimpleControl.cs代碼
using System;
using System.Web.UI;
namespace MyControl
{
public class LinksControl : Control
{
protected int _num=0;
public virtual int Num
{
get { return _num; }
set { _num=value; }
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write(Num.ToString());
}
}
}
這裏我們建立了一個很簡單的控件,它有一個整型屬性Num,只是在Render中簡單地輸出了這個屬性的值。下面我們在ASPx文件中訪問這個屬性值。在虛擬目錄下新建一個Simple.aspx文件,並輸入如下代碼:
例6-1代碼2:Simple.aspx代碼
<script runat="server" language="C#">
void Button1_Click(object sender, EventArgs e)
{
LC.Num++;
}
</script>
<%@Register TagPrefix="CG" Namespace="MyControl" %>
<html>
<body>
<form runat="server">
<CG:LinksControl ID="LC" runat="server" />
<asp:Button ID="Button1" runat="server" οnclick="Button1_Click"
Text="Button" />
</form>
</body>
</html>
在aspx文件中,添加了一個Button控件,並在它的單擊事件中給我們剛纔所定製的控件的Num屬性加1。下面在瀏覽器中運行Simple.aspx文件。這時,只出現一個數字0和一個按鈕。我們多次單擊按鈕,但數字始終爲1,並沒有如我們所預期的那個不斷增加。這是爲什麼呢?
其實大家應該都知道,客戶端向服務器發出請求,服務器做出響應後就不再維持此次請求客戶端的信息。也就是說,我們在瀏覽器中輸入一個網址向服務器發出請求,服務器做出響應並實例化LinksControl類,在把響應信息返回給客戶端後,控件就被釋放了。這時我們在網頁上單擊了按鈕,再次向服務器發出請求,服務器會再次實例化LinksControl類以做出響應。也就是說每次單擊按鈕,所操作的都是LinksControl類的不同實例,屬性值並沒有得到保存就很正常了。Web編程和WinForm編程模型真是天壤之別,真是讓人頭痛。
如何解決這個問題呢?Asp.Net中,把信息回傳給服務器時,提交了一個隱藏的ViewState控件,這個控件裏存放着頁面上的控件的狀態。也就是說在點按鈕時,把當前LinksControl對象的Num屬性回傳給服務器,服務器再根據這個值生成新的頁面。
如何獲得這個回傳值呢?Control類晨有一個ViewState屬性,它是一個集合,使用ViewState[“Num”]就可以得到Num的回傳值。好,打開SimpleControl.cs文件,並對屬性的代碼稍做修改如下:
例6-2代碼1:SimpleControl.cs代碼
using System;
using System.Web.UI;
namespace MyControl
{
public class LinksControl : Control
{
public virtual int Num
{
get
{
return ViewState["Num"]!=null ?
(int)ViewState["Num"] : 0;
}
set
{
ViewState["Num"]=value;
}
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write(Num.ToString());
}
}
}
現在再運行Simple.aspx,多次點擊按鈕,看看數字是否已經隨着點擊次數增長?