Подтвердить что ты не робот

Обработчики событий ASP.NET Button не срабатывают при первом щелчке, но при втором нажатии после PostBack

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

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

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

Любые идеи?

Пример определения кнопки (в пределах 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());
        }
    }
}
4b9b3361

Ответ 1

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

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

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

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

Конечно, когда я впервые просмотрел HTML, у моей кнопки был ID 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...
}

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

Ответ 2

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

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

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

Ответ 3

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

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

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

            SpecsControl.ID = "Aribtrary_Name";

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

Ответ 4

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

Ответ 5

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

например:

if (IsPostBack) {
    // Add handlers here ...
}

Ответ 7

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

Ответ 8

Даже у меня была та же проблема. причиной было "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");
    }
}