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

时间:2012-02-23 21:19:17

标签: c# asp.net webforms

我在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第一次提出这个问题的时候我正在做的项目,我最终做了一些完全不同的事情,但是,如果有办法做我想做的事情,我会非常喜欢知道如何。

8 个答案:

答案 0 :(得分:2)

您无法使用a code-render block(即<% =inline-expression %>)来设置<asp:Button>等Web服务器控件的属性。

这种语法主要是来自传统ASP的宿醉,如果你第一次遇到这个问题,那么

  

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

然后你做了正确的事。

答案 1 :(得分:1)

使用 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
    }
}

答案 2 :(得分:0)

您可以使用简单的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
    }
    

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

http://msdn.microsoft.com/en-us/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
}

答案 5 :(得分:0)

你可以假装它;您在控件上看到的事件处理程序被嵌入到asp.net框架中 - 它们有服务器和客户端支持 - 框架发出所有必要的连接以绑定服务器端控件,它是等效的HTML,以及所有事件一起。你不能简单地改变这些签名而不需要重新加工很多部分。

但是,你可以做的是定义自定义事件args;如果您派生自己的控件,那么您可以使用own custom event args that inherit from System.EventArgs

实现自己的事件处理程序

还有其他几种选择:

Client Callbacks

OnCommand

答案 6 :(得分:0)

正如这个线程所证明的那样,将变量(如i)的值直接从标记放入服务器控件并不是一件容易的事。正如Joe正确指出的那样,代码渲染块(&lt;%= i%&gt;)在服务器控件中不起作用。 &lt;%= i%&gt;语法在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意图的转变。

答案 7 :(得分:-1)

我不是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 />
}%>