繁体   English   中英

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

[英]Pass value from aspx to event handler in code behind

我在msdn论坛上提出了这个问题,除了一个人提出了一个实际的解决方法外,每个人都感到沮丧。


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

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

该代码成功渲染了10个表示"Click Here"按钮


我想要做的是使事件处理程序单击以i为参数的按钮。

    protected void MyButtonHandler(object sender, EventArgs e)
    {
        //do something with i
    }

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

您不能使用代码渲染块 (即<% =inline-expression %> )来设置Web服务器控件的属性,例如<asp:Button>

该语法主要是经典ASP的宿醉,如果您第一次遇到此问题,

...最终做了完全不同的事情

那你做对了

使用CommandName属性来区分按钮:

<%for (int i = 0; i < 10; i++) %>
<%{ %>
    <asp:Button runat="server" Text="Click Here" OnClick="MyButtonHandler" CommandName='cmd<%= i.ToString() %>'/>
<%} %>

然后在后面的代码中:

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

你可以用简单的JavaScript做到这一点

  1. 创建隐藏字段

     <input type="hidden" name="myButtonValue" id="myButtonValue" /> 
  2. 将onclick事件分配给按钮

     <asp:Button runat="server" Text="Click Here" OnClick="MyButtonHandler" OnClientClick="setValue(<%= i %>" /> 
  3. 创建JavaScript函数

     <script type="text/javascript"> function setValue(val) { document.getElementById('myButtonValue').value = val; } </script> 

    然后在代码中使用您的变量

     protected void MyButtonHandler(object sender, EventArgs e) { int i = 0; int.TryParse(Request.Form["myButtonValue"].ToString(), out i); //do somethign with i } 

我能想到的最稳定的方法是(在for循环内)有一个面板(占位符,您就知道了),并且该面板内部既有按钮又有一个ASP:Hidden控件或一个以i为值的隐藏标签。 在按钮单击事件中,您可以将sender转换为按钮,抓住该控件的父(面板)控件,然后获取隐藏的子控件。

您可以使用命令按钮和Button.Command事件

http://msdn.microsoft.com/zh-CN/library/system.web.ui.webcontrols.button.command.aspx

你最终会得到这样的东西。 (我尚未测试下面的代码)

<%for (int i = 0; i < 10; i++) %> 
<%{ %> 
 <asp:Button runat="server" Text="Click Here" 
               CommandName="something"
               CommandArgument=<%=i%> 
               onCommand="MyButtonHandler"  /> 
<%} %> 

void myButtonHandler(Object sender, CommandEventArgs e) 
{
     i = (int)e.CommandArgument;
     //do something with i
}

您可以伪造; 您在控件上看到的事件处理程序将被放入asp.net框架中-它们对服务器和客户端都有支持-该框架发出与服务器端控件相关的所有必要连线,与HTML等效的控件以及所有事件一起。 您不能简单地更改这些签名而不重做很多部分。

但是,您可以定义自定义事件args。 如果派生自己的控件,则可以使用继承自System.EventArgs的自定义事件args实现自己的事件处理程序

还有其他几种选择:

客户回调

OnCommand

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

我建议使用转发器将控制流从标记移到代码隐藏。 这样您就可以从后面的代码中设置命令参数。 这与asp.net的工作原理更加一致。 所以...

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

会变得更像

    <asp:Repeater ID="ButtonRepeater" runat="server" 
        onitemdatabound="ButtonRepeater_ItemDataBound">
        <ItemTemplate>
            <asp:Button id="MyButton" runat="server" Text="Click Here" OnClick="MyButtonHandler" />
        </ItemTemplate>
    </asp:Repeater>

当然,您仍然可以在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
        }
    }

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

这是一个范式转换,但与ASP.NET的意图是一致的。

我不是ASP方面的专家,但是您可以尝试类似的方法

<%for (int i = 0; i < 10; i++) %>
<%{ 
 // build the below string in ASP. Make the event handler MyubttonHanlder1,
 // MyButtonHanlder2, ... and so on, then echo it using response.Write. It  
 // will create 10 control each with its own handler. Create 10 handlers 
 // on the back end.

    <asp:Button runat="server" Text="Click Here" OnClick="MyButtonHandler"+i />
}%> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM