ASP.NET 自定义表达式
当我们以 <%=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 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 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 runat="server"
ConnectionString='<%#System.Web.Configuration.WebConfigurationManager.ConnectionStrings["MyMemberShipConnstr"] %>'
SelectCommand="select * from aspnet_roles"></asp:SqlDataSource>
<asp:GridView runat="server" DataSource>
</asp:GridView>
上面的代码照常执行,当我们在Page_load中调用了DataBind()方法时. 但是当我们将SqlDataSource控件和GridView调换位置时,异常就会抛出:The ConnectionString property has not been initialized. 那是因为在GridView进行数据绑定时 数据库连接字符串还没有初始化。