有人可以解释为什么你不能在ASP.Net中的服务器控制声明中使用内联代码块吗?
以下是一个简单的例子......
....
<form id="form1" runat="server">
<asp:Label ID="Label1" runat="server" Text="<%= SomeProperty %>"></asp:Label>
</form>
....
代码块按字面意思呈现给页面...
<span id="Label1"><%= SomeProperty %></span>
我最初的想法是它与页面生命周期中处理这些内容的顺序有关。据我所知,<%=...%>
块与代码隐藏中的Response.Write(...)
相当。并且由于服务器控件实际上没有像标记中声明的那样呈现,我想在进行渲染之前可能无法处理嵌入的代码块。
我会非常感激任何人都可以解释得更好。
但是,数据绑定代码块<%#...%>
在行为方式上明显不同,但任何人都可以告诉我为什么可以将它们嵌入到服务器控件中...
....
<asp:Repeater id=Repeater1 runat="server">
....
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval(“SomeProperty”) %>'></asp:Label>
</ItemTemplate>
....
</asp:Repeater>
....
这很好用。
答案 0 :(得分:7)
您对<%=...%>
语法大多正确。
这是一个在幕后发生的事情的例子:
<script runat="server">
public string SomeProperty { get { return "Hello World!"; } }
</script>
<form id="form1" runat="server">
<%= SomeProperty %>
<div>
<asp:Label ID="Label1" runat="server" Text="<%= SomeProperty %>"></asp:Label>
</div>
</form>
对此进行了解析,并创建了以下C#代码(我对其进行了简化):
private Label @__BuildControlLabel1()
{
Label @__ctrl = new Label();
this.Label1 = @__ctrl;
@__ctrl.ApplyStyleSheetSkin(this);
@__ctrl.ID = "Label1";
@__ctrl.Text = "<%= SomeProperty %>";
return @__ctrl;
}
private void @__Renderform1(HtmlTextWriter @__w, Control parameterContainer)
{
@__w.Write( SomeProperty );
@__w.Write("\r\n <div>\r\n ");
parameterContainer.Controls[0].RenderControl(@__w);
@__w.Write("\r\n </div>\r\n ");
}
以下是<%#...%>
语法在幕后发生的事情的示例:
<script runat="server">
public string SomeProperty { get { return "Hello World!"; } }
protected void Page_Load(object sender, EventArgs e) { Label1.DataBind(); }
</script>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="<%# SomeProperty %>"></asp:Label>
</div>
</form>
生成此代码:
private Label @__BuildControlLabel1()
{
Label @__ctrl = new Label();
this.Label1 = @__ctrl;
@__ctrl.ApplyStyleSheetSkin(this);
@__ctrl.ID = "Label1";
@__ctrl.DataBinding += new System.EventHandler(this.@__DataBindingLabel1);
return @__ctrl;
}
public void @__DataBindingLabel1(object sender, EventArgs e)
{
Label dataBindingExpressionBuilderTarget = ((Label)(sender));
Page Container = ((Page)(dataBindingExpressionBuilderTarget.BindingContainer));
dataBindingExpressionBuilderTarget.Text = System.Convert.ToString( SomeProperty , System.Globalization.CultureInfo.CurrentCulture);
}
正如您所看到的,<%=...%>
语法可以在服务器控件的属性之外使用,以直接呈现返回的值。另一方面,<%#...%>
语法为标签的DataBinding事件生成事件处理程序。此事件将标签属性的值设置为SomeProperty的值。每当调用DataBind方法时都会触发DataBinding事件,这就是我将该调用添加到Page_Load事件的原因。
希望这有助于您了解它们之间的区别。
答案 1 :(得分:3)
您可以创建自定义ExpressionBuilder,以便使用<%$ Code: SomeProperty %>
答案 2 :(得分:0)
您可以创建自定义数据绑定控件,例如
namespace FooBar.WebControls
{
public class DataBoundPlaceHolder:PlaceHolder
{
private bool hasDataBound = false;
protected override void CreateChildControls()
{
if (!hasDataBound)
{
this.DataBind();
hasDataBound = true;
}
base.CreateChildControls();
}
}
}
然后将代码包装在这个新控件中,并使用<%# %>
语法,例如
<%@ Register TagPrefix="WebControls" Namespace="FooBar.WebControls" Assembly="FooBar" %>
<form id="form1" runat="server">
<WebControls:DataBoundPlaceHolder runat="server">
<asp:Label ID="Label1" runat="server" Text='<%# SomeProperty %>'></asp:Label>
</WebControls:DataBoundPlaceHolder>
</form>