Передать значение из aspx в обработчик событий в коде - PullRequest
4 голосов
/ 24 февраля 2012

Я задавал этот вопрос на форумах 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 ]

2 голосов
/ 24 февраля 2012

Вы не можете использовать блок визуализации кода (т.е. <% =inline-expression %>) для установки свойств элементов управления веб-сервера, таких как <asp:Button>.

Этот синтаксис - это в основном похмелье от классического ASP, и если вы впервые столкнулись с этой проблемой, вы

... закончил тем, что делал что-то совершенно другое

тогда вы поступили правильно.

1 голос
/ 24 февраля 2012

Используйте свойство 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
    }
}
0 голосов
/ 24 февраля 2012

Как доказывает этот поток, поместить значение переменной, такой как i, в элемент управления сервером непосредственно из разметки нетривиально. Как правильно заметил Джо, блоки рендеринга кода (<% = 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>

Конечно, вы все равно можете добавить все HTML, которые хотите, в теги ItemTemplate. Затем в коде добавьте следующее.

    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.

0 голосов
/ 24 февраля 2012

Вы можете подделать это;обработчики событий, которые вы видите на элементах управления, встроены в инфраструктуру asp.net - для них есть поддержка на стороне сервера и на стороне клиента - инфраструктура испускает всю необходимую проводку, чтобы связать серверный элемент управления, его HTML-эквивалент и все событиявсе вместе.Вы не можете просто изменить эти подписи, не переделывая много частей.

Однако вы можете определить собственные аргументы событий;если вы получаете свой собственный элемент управления, то вы можете реализовать свой собственный обработчик событий с вашими собственными собственными пользовательскими аргументами событий, которые наследуются от System.EventArgs

Существует несколько других альтернатив:* Клиентские обратные вызовы .

OnCommand

0 голосов
/ 24 февраля 2012

Я не эксперт в 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 />
}%> 
0 голосов
/ 24 февраля 2012

Вы можете использовать командную кнопку и событие 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
}
0 голосов
/ 24 февраля 2012

Самый стабильный метод, который я могу придумать, это иметь (внутри вашего цикла for) панель (заполнитель, как вы понимаете), а внутри этой панели есть как кнопка, так и ASP: Hidden элемент управления или скрытая метка со значением i. В событии нажатия кнопки вы можете присвоить sender кнопку, захватить родительский (панель) элемент управления, а затем получить скрытый дочерний элемент управления.

0 голосов
/ 24 февраля 2012

Вы можете сделать это простым 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
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...