Фон: Я настраиваю существующий ASP.NET / приложение C#. Это имеет свою собственную небольшую "платформу" и конвенции для разработчиков следовать при расширении/настройке ее функциональности. Я в настоящее время расширяю часть, он - административная функциональность, которой платформа предоставляет контракт для осуществления реализации GetAdministrationInterface()
метод, который возвращается System.Web.UI.Control
. Этот метод называют во время Page_Load()
метод страницы, размещающей графический интерфейс.
Проблема: у Меня есть три кнопки в моем GUI, каждая из которых были присвоены Обработчик событий. Мои загрузки 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());
}
}
}
Боже правый! Я знал, что это будет что-то настолько глупое. Конечно, это чисто моя вина и отсутствие знаний в ASP .NET.
После множества поисков в Google и в конечном итоге блокировки Google по подозрению в том, что он является ботом, выполняющим автоматические скрипты, мне удалось втиснуть последний поиск и наткнуться на эту статью. Будучи уже на грани того, чтобы сдаться, я изо всех сил старался прочитать статью, не пропуская по 10 строк за раз и не рассматривая красивые картинки. В разделе под названием Присвоение идентификаторов динамически создаваемым элементам управления я прочитал эти волшебные и самые радостные слова:
Если вы просмотрите исходный HTML до нажатия на нерабочую кнопку и после нажатия, то заметите небольшую разницу. Кнопки имеют разные HTML ID до и после отката. Я получил ctl04 и ctl05 до отката и ctl02 и ctl03 после отката.
Кнопка ASP.NET распознает события, проверяя наличие значения для своего ID в коллекции Request.Form. (На самом деле все происходит иначе, и элементы управления не проверяют коллекцию Request.Form самостоятельно. Страница передает пост-данные элементам управления по их идентификаторам и элементам управления, которые зарегистрированы для получения уведомлений о пост-данных). ASP.NET не запускает событие Click, потому что ID кнопки изменился между пост-бэками. Кнопка, которую вы нажали, и кнопка, которую вы видите после - это разные кнопки для ASP.NET.
Конечно, когда я просматривал HTML в первый раз, моя кнопка имела ID ctl04$ctl36
. После щелчка на кнопке моя кнопка имела ID 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...
}
Отличный способ провести два дня...
Несмотря на то, что его трудно узнать, не видя полного метода Page_load, он немного пахнет так, как будто обработчики событий не подключаются, пока страница не будет перезагружена.
например:
if (IsPostBack) {
// Add handlers here ...
}