當我們以 <%=DateTime.Now.ToString() %>(<%%>)在頁面裡呈現資料時,它到底是如何工作的呢?
據我發現,當頁面裡麵包含<%%>符號時,頁面在解析 編譯期間 將在__BuildControlform1()函數裡自動產生調用SetRenderMethodDelegate()方法( __ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1));):如下:
[DebuggerNonUserCode]
private HtmlForm __BuildControlform1()
{
HtmlForm __ctrl = new HtmlForm();
base.form1 = __ctrl;
__ctrl.ID = "form1";
Literal __ctrl1 = this.__BuildControlLiteral1();
IParserAccessor __parser = __ctrl;
__parser.AddParsedSubObject(__ctrl1);
__ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1));
return __ctrl;
}
private void __Renderform1(HtmlTextWriter __w, Control parameterContainer)
{
__w.Write("\r\n ");
__w.Write(DateTime.Now.ToString());
__w.Write("\r\n <div>\r\n ");
parameterContainer.Controls[0].RenderControl(__w);
__w.Write("\r\n </div>\r\n ");
}
從上面代碼我們可以發現,頁面所有<%%>單獨出現的都由一個Literal控制項來呈現。並在BuildControlForm1裡自動添加Literal控制項並調用SetRenderMethodDelegate().
但是當我們
<asp:TextBox ID="TextBox1" runat="server" Text=<%=DateTime.Now.ToString() %>></asp:TextBox>
為什麼會編譯出錯呢?那是因為基於SetRenderMethodDelegate()方法是服務產生頁面的Body部分(The model based on SetRenderMethodDelegate works for building the body of the page at render time, not for setting object properties at parse time).
那麼怎麼以聲明的方式 控制項屬性?資料繫結運算式:
<asp:TextBox ID="TextBox1" runat="server" Text="<%#DateTime.Now.ToString() %>"></asp:TextBox>
[DebuggerNonUserCode]
private TextBox __BuildControlTextBox1()
{
TextBox __ctrl = new TextBox();
base.TextBox1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "TextBox1";
__ctrl.DataBinding += new EventHandler(this.__DataBindingTextBox1);
return __ctrl;
}
public void __DataBindingTextBox1(object sender, EventArgs e)
{
TextBox dataBindingExpressionBuilderTarget = (TextBox) sender;
Page Container = (Page) dataBindingExpressionBuilderTarget.BindingContainer;
dataBindingExpressionBuilderTarget.Text = Convert.ToString(DateTime.Now.ToString(), CultureInfo.CurrentCulture);
}
由此我們發現代碼自動註冊了TextBox的DataBind事件。
日期運算式只有在DataBind方法被調用時才有效。所以我們要上面的代碼呈現出我們希望的結果,我們需要在Page_Load中手動調用DataBind(). DataBind方法能被頁面或特定的控制項來觸發。
但是在資料繫結運算式(#)外,還有一種運算式($)dynamic expression. 為什麼要有另外一種運算式呢?先看看:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString='<%#System.Web.Configuration.WebConfigurationManager.ConnectionStrings["MyMemberShipConnstr"] %>'
SelectCommand="select * from aspnet_roles"></asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1">
</asp:GridView>
上面的代碼照常執行,當我們在Page_load中調用了DataBind()方法時. 但是當我們將SqlDataSource控制項和GridView調換位置時,異常就會拋出:The ConnectionString property has not been initialized. 那是因為在GridView進行資料繫結時 資料庫連接字串還沒有初始化。