首先,属性是各种.net语言的基本语法。而我们常说的控件属性是指控件类中用public修饰的属性。
见Lable的Text属性:
[Bindable(true), DefaultValue(""), Localizable(true), PersistenceMode(PersistenceMode.InnerDefaultProperty), WebCategory("Appearance"), WebSysDescription("Label_Text")]
public virtual string Text
{
get
{
object obj = this.ViewState["Text"];
if (obj != null)
{
return (string)obj;
}
return string.Empty;
}
set
{
if (this.HasControls())
{
this.Controls.Clear();
}
this.ViewState["Text"] = value;
}
}
二、属性的持久化
Lable的Text属性都干了些什么呢?为什么不直接封装一个string字段呢?
在回答这些问题前,我们先看看这样一个实验。
话说:Lable有一个儿子,他是这样的:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
namespace CustomServerControl
{
public class MemorylessLable : Label
{
public override string Text
{
get;
set;
}
}
}
有一天Lable和儿子排好队,站出相同的姿势:
<div>
<csc:MemorylessLable ID="MemorylessLable1" Text="MemorylessLable" runat="server">
</csc:MemorylessLable>
<br />
<asp:Button ID="btnMemorylessLable" runat="server" Text="MemorylessLableAdd(?)" OnClick="btnMemorylessLable_Click" />
</div>
<div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<asp:Button ID="btnLabel" runat="server" Text="LabelAdd(?)" OnClick="btnLabel_Click" />
</div>
他们做着同样的事情:
protected void btnMemorylessLable_Click(object sender, EventArgs e)
{
MemorylessLable1.Text += "?";
}
protected void btnLabel_Click(object sender, EventArgs e)
{
Label1.Text += "?";
}
但是......
但是,是你看到的结果。但是,这又是为什么呢?
我们回顾一下HTTP协议的工作模式:HTTP是一种无状态的断开式连接模式,也就是说,客户端向服务端发送请求,服务端做出响应后就不再维持此次请求客户端的信息。在默认情况下,多次请求来自同一个客户端还是多个不同的客户端,对于服务端来说处理方式没有什么不同。
1、视图状态
现在,我们已经弄清了MemorylessLable 中Text属性没有记忆的原因。回到问题的开始,Lable的Text属性又干了些什么呢?是什么让他看上去有了记忆?
我们看生成的HTML中有一个name为“__VIEWSTATE”的隐藏表单域: