2009-08-13 4 views
9

Kann jemand erklären, warum Sie keine Inline-Code-Blöcke in Serversteuerdeklarationen in ASP.Net verwenden können?Gibt es eine Möglichkeit, Code-Behind-Eigenschaftswerte deklarativ an Serversteuerelemente weiterzugeben?

Das folgende ist ein einfaches Beispiel ...

.... 
<form id="form1" runat="server"> 
    <asp:Label ID="Label1" runat="server" Text="<%= SomeProperty %>"></asp:Label> 
</form> 
.... 

Der Codeblock auf der Seite wörtlich wiedergegeben wird ...

<span id="Label1"><%= SomeProperty %></span> 

Meine ersten Gedanken sind es mit der Bestellung zu tun hat dass diese Dinge im Seitenlebenszyklus verarbeitet werden. Die <%=...%> Blöcke sind, wie ich es verstehe, äquivalent zu Response.Write(...) in Code-behind. Und da das Server-Steuerelement nicht wirklich so dargestellt wird, wie es im Markup deklariert ist, ist es wahrscheinlich nicht möglich, einen eingebetteten Codeblock zu verarbeiten, bevor dieses Rendering stattfindet.

Ich wäre sehr dankbar, dass jemand das ein wenig besser erklären könnte.

jedoch die Datencodeblock <%#...%> Bindung ist offensichtlich anders in der Art und Weise verhält es sich, aber kann mir jemand sagen, warum es möglich ist, diese innerhalb einer Server-Steuerelement einzubetten ...

.... 
<asp:Repeater id=Repeater1 runat="server"> 
    .... 
    <ItemTemplate> 
     <asp:Label ID="Label1" runat="server" Text='<%# Eval(“SomeProperty”) %>'></asp:Label> 
    </ItemTemplate> 
    .... 
</asp:Repeater> 
.... 

Dies funktioniert fein.

+0

[Set Visible-Eigenschaft mit Server-Tag <%= %> in Framework 3.5] (http://stackoverflow.com/questions/9595851/set-visible-property-with-server-tag-in-framework-3-5) –

Antwort

7

Ihr meist rechts über die <%=...%> Syntax. Hier ist ein Beispiel dafür, was unter der Haube passiert:

<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> 

Dieses analysiert wird und die folgende C# -Code erstellt wird (ich habe es ein wenig vereinfacht):

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 "); 
} 

Hier ist ein Beispiel von dem, was für die <%#...%> Syntax unter der Haube passiert:

<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> 

Erzeugt diesen Code:

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); 
} 

Wie Sie sehen können, kann die <%=...%>-Syntax außerhalb der Eigenschaften eines Serversteuerelements verwendet werden, um den zurückgegebenen Wert direkt zu rendern. Auf der anderen Seite generiert die Syntax <%#...%> einen Event-Handler für das DataBinding-Ereignis des Labels. Dieses Ereignis legt den Wert der Label-Eigenschaft auf den Wert von SomeProperty fest. Das DataBinding-Ereignis wird immer dann ausgelöst, wenn die DataBind-Methode aufgerufen wird. Aus diesem Grund habe ich diesen Aufruf dem Page_Load-Ereignis hinzugefügt.
Hoffentlich hilft Ihnen das, den Unterschied zwischen ihnen zu verstehen.

+0

Solide Erklärung. – Merritt

3

Sie eine benutzerdefinierte schaffen könnte ExpressionBuilder so verwenden Sie so etwas wie <%$ Code: SomeProperty %>

+0

Interessant - danke für die Antwort. Der Teil rechts vom Doppelpunkt ist also ein Ausdruck, den der ExpressionBuilder auswerten müsste. Müsste ich deshalb Reflektion verwenden, um die Eigenschaft vom Seitenobjekt zu lesen? Ich kann nicht sehen, wie das funktionieren würde, da der ExpressionBuilder keinen Verweis auf die Seite hätte. Fehle ich etwas? –

+1

ExpressionBuilders interessanteste Methode ist GetCodeExpression, für die Sie einfach eine CodeSnippetExpression des Bits rechts vom Doppelpunkt (die Sie von entry.Expression.Trim() erhalten können) –

+0

Oh, und wenn Sie das finden antworte interessant/nützlich, gib mir wenigstens eine Stimme;) –

0

Sie können ein benutzerdefiniertes datengebundenes Steuerelement erstellen, z.

namespace FooBar.WebControls 
{ 
    public class DataBoundPlaceHolder:PlaceHolder 
    { 
     private bool hasDataBound = false; 
     protected override void CreateChildControls() 
     { 
      if (!hasDataBound) 
      { 
       this.DataBind(); 
       hasDataBound = true; 
      } 
      base.CreateChildControls(); 
     } 
    } 
} 

Dann wickeln Sie den Code in dieser neuen Steuerung und verwenden Sie die <%# %> Syntax, z.B.

<%@ 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> 
Verwandte Themen