有没有办法以声明方式将代码隐藏属性值传递给服务器控件?

发布于 2024-08-01 23:20:20 字数 994 浏览 2 评论 0原文

谁能解释为什么不能在 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>
....

这工作得很好。

Can anyone explain why you can’t use inline code blocks within server control declarations in ASP.Net?

The following is a simple example...

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

The code block is rendered literally to the page...

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

My initial thoughts are it has to do with the order that these things are processed in the page life-cycle. The <%=...%> blocks are, as I understand it, equivalent to a Response.Write(...) in code-behind. And since the server control is not actually rendered as declared in the markup, I suppose it may not be possible to process an embedded code block before this rendering takes place.

I would be very grateful of anyone could explain that a little better.

However, the data binding code block <%#...%> is obviously different in the way it behaves, but can anyone tell me why it is possible to embed these within a server control...

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

This works fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟酉 2024-08-08 23:20:20

您可以创建一个自定义 ExpressionBuilder 以便您使用类似 <%$ Code: SomeProperty %>

You could create a custom ExpressionBuilder so you use something like <%$ Code: SomeProperty %>

酒几许 2024-08-08 23:20:20

您可以创建一个自定义数据绑定控件,例如

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>

You can create a custom databound control, e.g.

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

Then wrap your code in this new control, and use the <%# %> syntax, e.g.

<%@ 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>
萌梦深 2024-08-08 23:20:20

您对 <%=...%> 语法的看法大多是正确的。
以下是幕后发生的情况的示例:

<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 事件的原因。

希望这能帮助您理解它们之间的区别。

You're mostly right about the <%=...%> syntax.
Here is an example of what happens under the hood:

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

This is parsed and the following C# code is created (I've simplified it a bit):

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

Here is an example of what happens under the hood for the <%#...%> syntax:

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

Generates this code:

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

As you can see the <%=...%> syntax can be used outside of a server control's properties to directly render the returned value. On the other hand the <%#...%> syntax generates a event handler for the DataBinding event of the label. This event sets the value of the label's property to the value of SomeProperty. The DataBinding event fires whenever the DataBind method is called which is why I added that call to the Page_Load event.
Hopefully this will help you understand the difference between them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文