将值从 aspx 传递到后面代码中的事件处理程序

Sam*_*ica 5 c# asp.net webforms

我在 msdn 论坛上问了这个问题,除了一个人提出了实际上的解决方法之外,每个人都被难住了。


在我的 Webforms 项目中,我有一些如下所示的 aspx 代码:

<%for (int i = 0; i < 10; i++) %>
<%{ %>
    <asp:Button runat="server" Text="Click Here" OnClick="MyButtonHandler" />
<%} %>
Run Code Online (Sandbox Code Playgroud)

该代码成功呈现了 10 个按钮,上面写着"Click Here"


我想做的是创建一个事件处理程序,用于单击作为i参数的按钮。

    protected void MyButtonHandler(object sender, EventArgs e)
    {
        //do something with i
    }
Run Code Online (Sandbox Code Playgroud)

关于当我第一次在 msdn 上问这个问题时我正在从事的项目,我最终做了一些完全不同的事情,但是,如果有一种方法可以做我想做的事情,我非常想知道如何。

Dev*_*vin 0

正如该线程所证明的那样,将变量(如 i)的值直接从标记放入服务器控件中并非易事。正如 Joe 正确指出的那样,代码渲染块 (<%=i %>) 在服务器控件中不起作用。<%=i %> 语法在 html 标记中效果很好,但服务器控件(如按钮)不支持它。

我建议使用转发器将控制流从标记移动到代码隐藏。这将允许您从后面的代码设置命令参数。这更符合 asp.net 的工作方式。所以 ...

    <%for (int i = 0; i < 10; i++) %>
    <%{ %>
      <asp:Button runat="server" Text="Click Here" OnClick="MyButtonHandler" />
    <%} %>
Run Code Online (Sandbox Code Playgroud)

会变得更像

    <asp:Repeater ID="ButtonRepeater" runat="server" 
        onitemdatabound="ButtonRepeater_ItemDataBound">
        <ItemTemplate>
            <asp:Button id="MyButton" runat="server" Text="Click Here" OnClick="MyButtonHandler" />
        </ItemTemplate>
    </asp:Repeater>
Run Code Online (Sandbox Code Playgroud)

当然,您仍然可以在 ItemTemplate 标记中添加所需的所有 html。然后在后面的代码中添加以下内容。

    protected void Page_Load(object sender, EventArgs e)
    {
        this.ButtonRepeater.DataSource = new[] { 1, 2, 3, 4, 5 }; // however many items you want
        this.ButtonRepeater.DataBind();
    }

    protected void MyButtonHandler(Object sender, EventArgs e)
    {
        Button b = sender as Button;
        if (b != null)
        {
            string cmdName = b.CommandName;
            // logic based on cmdName
        }
    }

    protected void ButtonRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        var button = e.Item.FindControl("MyButton") as Button;
        if (button != null)
        {
            var buttonNumber = e.Item.DataItem.ToString();
            button.CommandName = buttonNumber;
            button.ID = string.Format("MyButton_{0}", buttonNumber); // required to prevent event validation error
        }
    }
Run Code Online (Sandbox Code Playgroud)

实际上,我通过在事件处理程序中的 cmdName 变量上放置一个断点来对此进行测试。它是根据我单击的按钮进行适当设置的。

这是一种范式转变,但这种转变符合 ASP.NET 的意图。