2009-08-13 23 views
9

Có ai có thể giải thích tại sao bạn không thể sử dụng các khối mã nội tuyến trong các khai báo kiểm soát máy chủ trong ASP.Net không?Có cách nào để khai báo các giá trị thuộc tính mã phía sau để điều khiển máy chủ không?

Sau đây là một ví dụ đơn giản ...

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

Các khối mã được render theo nghĩa đen để trang ...

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

những suy nghĩ ban đầu của tôi là nó đã làm với thứ tự rằng những thứ này được xử lý trong vòng đời của trang. Các khối <%=...%> là, như tôi hiểu nó, tương đương với một số Response.Write(...) trong mã sau. Và vì điều khiển máy chủ không thực sự được hiển thị như được khai báo trong đánh dấu, tôi cho rằng nó có thể không thể xử lý một khối mã được nhúng trước khi việc hiển thị này diễn ra.

Tôi sẽ rất biết ơn bất kỳ ai có thể giải thích tốt hơn một chút.

Tuy nhiên, dữ liệu ràng buộc khối mã <%#...%> rõ ràng là khác nhau trong cách ứng xử, nhưng bất cứ ai có thể cho tôi biết lý do tại sao người ta có thể nhúng các bên trong một điều khiển máy chủ ...

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

tác phẩm này khỏe.

+0

[Thiết lập thuộc tính Visible với máy chủ thẻ <%= %> trong Framework 3.5] (http://stackoverflow.com/questions/9595851/set-visible-property-with-server-tag-in-framework-3-5) –

Trả lời

7

chủ yếu của bạn đúng về cú pháp <%=...%>. Dưới đây là một ví dụ về những gì xảy ra dưới mui xe:

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

này được phân tách và C# mã sau đây được tạo ra (tôi đã đơn giản hóa nó một chút):

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

Dưới đây là một ví dụ những gì xảy ra dưới mui xe cho <%#...%> cú pháp:

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

Tạo mã này:

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

Như bạn có thể thấy cú pháp <%=...%> có thể được sử dụng bên ngoài thuộc tính của điều khiển máy chủ để trực tiếp hiển thị giá trị trả về. Mặt khác, cú pháp <%#...%> tạo ra một trình xử lý sự kiện cho sự kiện DataBinding của nhãn. Sự kiện này đặt giá trị của thuộc tính nhãn thành giá trị của SomeProperty. Sự kiện DataBinding kích hoạt bất cứ khi nào phương thức DataBind được gọi đó là lý do tại sao tôi đã thêm cuộc gọi đó vào sự kiện Page_Load.
Hy vọng điều này sẽ giúp bạn hiểu sự khác biệt giữa chúng.

+0

Giải thích cụ thể. – Merritt

3

Bạn có thể tạo một phong tục ExpressionBuilder để bạn sử dụng một cái gì đó giống như <%$ Code: SomeProperty %>

+0

Thú vị - cảm ơn bạn đã trả lời. Vì vậy, một phần bên phải của dấu hai chấm là một biểu thức mà ExpressionBuilder sẽ cần phải đánh giá. Vậy tôi sẽ phải sử dụng sự phản chiếu để đọc thuộc tính từ đối tượng trang? Tôi không thể thấy làm thế nào mà sẽ làm việc cho rằng ExpressionBuilder sẽ không có một tham chiếu đến trang. Tui bỏ lỡ điều gì vậy? –

+1

Phương thức thú vị nhất của ExpressionBuilder là GetCodeExpression, mà bạn chỉ cần trả về một CodeSnippetExpression của bit ở bên phải dấu hai chấm (mà bạn có thể lấy từ entry.Expression.Trim()) –

+0

Ồ, và nếu bạn tìm thấy trả lời thú vị/hữu ích, ít nhất là cho tôi một phiếu bầu;) –

0

Bạn có thể tạo điều khiển dữ liệu tùy chỉnh, ví dụ:

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

Sau đó, bọc mã của bạn trong điều khiển mới này và sử dụng cú pháp <%# %>, ví dụ:

<%@ 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> 
Các vấn đề liên quan