2009-08-13 54 views
9

任何人都可以解釋爲什麼你不能在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

(http://stackoverflow.com/questions/9595851/set-visible-property-with-server-tag-in-framework-3-5 [設置可見與服務器標籤<%= %>在Framework 3.5屬性] ) – 2013-03-02 08:15:00

回答

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([email protected]__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事件中的原因。
希望這可以幫助你理解它們之間的區別。

+0

確實的解釋。 – Merritt 2009-08-15 02:41:35

3

你可以創建一個自定義ExpressionBuilder,所以你使用類似<%$ Code: SomeProperty %>

+0

有趣的 - 感謝您的答覆。因此,冒號右側的部分是ExpressionBuilder需要評估的表達式。因此,我是否必須使用反射來從頁面對象讀取屬性?由於ExpressionBuilder沒有對頁面的引用,我無法看到這將如何工作。我錯過了什麼嗎? – 2009-08-14 08:53:20

+1

ExpressionBuilder最有趣的方法是GetCodeExpression,您只需要將該位的CodeSnippetExpression返回到冒號右邊(可以從entry.Expression.Trim()獲得) – 2009-08-18 14:29:12

+0

哦,如果您發現這個回覆有趣/有用,至少給我一票;) – 2009-08-18 14:29:44

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> 
相關問題