Обработчики событий ASP .NET Button запускаются не при первом щелчке, а при втором щелчке после PostBack - PullRequest
35 голосов
/ 04 мая 2010

Справочная информация: Я настраиваю существующее приложение ASP .NET / C #. У него есть своя небольшая «структура» и соглашения, которым разработчики должны следовать при расширении / настройке своей функциональности. В настоящее время я расширяю некоторые из его административных функций, к которым инфраструктура предоставляет контракт для обеспечения реализации метода GetAdministrationInterface(), который возвращает System.Web.UI.Control. Этот метод вызывается во время Page_Load() метода страницы, на которой размещен интерфейс GUI.

Проблема: У меня есть три кнопки в моем графическом интерфейсе, каждой из которых был назначен обработчик событий. Мой административный интерфейс отлично загружается, но нажатие на любую из кнопок не дает того, чего я от них ожидаю. Однако, когда я нажимаю их второй раз, кнопки работают.

Я установил точки останова в начале каждого метода обработчика событий и прошел через мой код. При первом клике ни один из обработчиков событий не сработал. По второму клику они выстрелили.

Есть идеи?

Пример определения кнопки (в пределах GetAdministrationInterface)

public override Control GetAdministrationInterface()
{
    // more code...

    Button btn = new Button();
    btn.Text = "Click Me!";
    btn.Click += new EventHandler(Btn_Click);

    // more code...
}

Пример определения метода обработчика события

void Btn_Click(object sender, EventArgs e)
{
    // Do Something
}

Page_Load Метод, который вызывает GetAdministrationInterface

protected void Page_Load(object sender, System.EventArgs e)
{
    if (!Page.IsAsync)
    {
        List<AdministrationInterface> interfaces = <DATABASE CALL>;
        foreach(AdministrationInteface ai in interfaces)
        {
            placeholderDiv.Controls.Add(ai.GetAdministrationInterface());
        }
    }
}

Ответы [ 8 ]

65 голосов
/ 07 мая 2010

Боже мой! Я знал, что это будет что-то глупое. Чисто моя вина, конечно, и мое отсутствие знаний в ASP .NET.

После множества поисков в Google и, в конечном итоге, их заблокировало Google по подозрению в том, что он бот, выполняющий автоматические скрипты, мне удалось в последний раз протиснуться и наткнуться на эту статью Уже в момент сдачи, я старался изо всех сил читать статью, не пропуская 10 строк за раз или ища красивые картинки. В разделе под названием Назначение идентификаторов для динамически создаваемых элементов управления я прочел следующие волшебные и самые радостные слова:

Если вы просматриваете исходный HTML-код до того, как нажмете нерабочую кнопку, и после того, как нажмете ее, вы заметите небольшую разницу. Кнопки имеют разные идентификаторы HTML до и после постбэка. Я получил ctl04 и ctl05 до постбека и ctl02 и ctl03 после постбека.

Кнопка ASP.NET распознает события, проверяя значение своего идентификатора в коллекции Request.Form. (По правде говоря, это происходит иначе, и элементы управления не проверяют сбор Request.Form самостоятельно. Страница передает данные поста элементам управления по их идентификаторам и элементам управления, которые зарегистрированы для уведомления о данных поста). ASP.NET не запускает событие Click, потому что идентификатор кнопки менялся между постбеками. Кнопка, которую вы нажали, и кнопка, которую вы видите после, являются разными кнопками для ASP.NET.

Конечно, при первом просмотре HTML-кода у моей кнопки был идентификатор ctl04$ctl36. После нажатия на кнопку у моей кнопки был идентификатор ctl04$ctl33.

Итак, вот оно! Все, что мне нужно было сделать, это установить ID на кнопках и просто! Мои обработчики событий теперь вызываются!

Пример раствора:

public override Control GetAdministrationInterface()
{
    // more code...

    Button btn = new Button();
    btn.Text = "Click Me!";
    // !!THE BANE OF MY EXISTENCE!!
    btn.ID = "The_Bane_of_My_Existence";
    // !!THE BANE OF MY EXISTENCE!!
    btn.Click += new EventHandler(Btn_Click);

    // more code...
}

Какой отличный способ провести два дня ...

18 голосов
/ 20 октября 2013

У меня была такая же проблема, но принятый ответ здесь не вызывал ее. У меня было текстовое поле и кнопка поиска, и, нажав кнопку в первый раз, поиск не выполнялся. Обработчик события кнопки не был нажат. Но нажатие кнопки во второй раз вызвало событие на сервере. Вот почему:

Если у вас есть <asp:Textbox> с AutoPostBack, установленным на true, после того, как вы введете текстовое поле, а затем нажмете кнопку, текстовое поле немедленно вызывает обратную передачу, как только теряет фокус. Таким образом, даже нажатие кнопки не считается (страница уже отозвана в результате события текстового поля). Вот почему, когда вы нажимаете кнопку второй раз, это работает, потому что текстовое поле не участвует во втором постбэк.

Установите AutoPostBack свойство <asp:Textbox> на false, чтобы решить эту проблему.

5 голосов
/ 04 января 2015

Быстрое решение - установить идентификатор для элемента управления ASCX, который вы загружаете на страницу. Например, если ваш код такой:

        UserControl SpecsControl = (UserControl)Page.LoadControl("../name.ascx");
        SpecsContainer.Controls.Add(SpecsControl);

тогда вам нужно добавить строку (перед Controls.Add):

            SpecsControl.ID = "Aribtrary_Name";

Тогда ваш метод-обработчик запускается при первом клике.

1 голос
/ 27 августа 2015

Для меня это были UpdatePanel, моя кнопка и мой TextBox были внутри UpdatePanel, поэтому, когда я выполнял постбэк, это вызывало странное поведение. Это взяло это вне UpdatePanel, и это исправило это.

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

Я столкнулся с той же проблемой. Моя кнопка застыла после первого нажатия. Для меня эта досадная проблема была решена, когда я отключил атрибут кнопки EnableViewState.

0 голосов
/ 02 сентября 2015

Даже у меня была такая же проблема. причина была "localhost: 1656 / secure / login.aspx? ReturnUrl =% 2f ". если запрос содержит % 2f в качестве строки запроса, первое сообщение не будет выполнено, даже если «% 2f » представляет « / ».

один из способов избежать этого - проверка состояния в pageload

protected void Page_Load(object sender, EventArgs e)
{
    string queryString = Request.QueryString.ToString();
    if(queryString == "ReturnUrl=%2f")
    {
        Response.Redirect("/secure/login.aspx");
    }
}
0 голосов
/ 10 декабря 2014

У меня была такая же проблема. И я искал в интернете, я не нашел решения. После этого я нашел образец кода и использовал его. Это сработало для меня. Ссылка на сайт ниже:

http://www.c -sharpcorner.com / UploadFile / abhikumarvatsa / вызывающей ан-Asp-Net-C-Sharp-метод-веб-метод, используя-JavaScript /

0 голосов
/ 04 мая 2010

Хотя трудно точно знать, не видя полного метода Page_load, он немного пахнет, как обработчики событий не подключаются до тех пор, пока страница не будет перезагружена.

Например:

if (IsPostBack) {
    // Add handlers here ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...