Обработчики событий 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());
}
}
}
Ответы
Ответ 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 ...
}
Ответ 6
У меня была такая же проблема. И я искал в Интернете, я не нашел решения. После этого я нашел образец кода, и я его использовал. Это сработало для меня. Ссылка на веб-сайт ниже:
http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/calling-an-Asp-Net-C-Sharp-method-web-method-using-javascript/
Ответ 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");
}
}