У меня есть страница и пользовательский элемент управления & mdash; мы будем называть их Detail.aspx и Selector.ascx.
Допустим, на странице показаны подробности отдельных записей в базе данных. Пользовательский элемент управления в основном состоит из элемента управления DropDownList и некоторого связанного HTML. DropDownList отображает список других записей для переключения в любое время.
Когда DropDownList запускает событие SelectedIndexChanged, я бы хотел, чтобы родительская страница, в данном случае Detail.aspx, обрабатывала его. В конце концов, ему нужно знать, что было выбрано, чтобы он мог соответствующим образом изменить URL-адрес и отображаемые данные и т. Д.
Чтобы сделать это, я сделал то, что обычно делаю, что также говорит главный ответ в этом вопросе StackOverflow :
public event EventHandler DropDownSelectedIndexChanged
{
add
{
MyDropDownList.SelectedIndexChanged += value;
}
remove
{
MyDropDownList.SelectedIndexChanged -= value;
}
}
Приведенный выше код появляется в файле кода Selector.ascx.cs.
В результате на Detail.aspx я могу использовать его так:
<cc1:RecordSelector ID="RecordSelector1" runat="server"
OnDropDownSelectedIndexChanged="RecordSelector1_DropDownSelectedIndexChanged" />
Пока ничего необычного или удивительного.
Вот моя проблема:
Это вызывает NullReferenceException
, когда браузер нажимает Detail.aspx.
Отладка проблемы показывает, что при первом обращении к странице публичное событие, которое я показывал выше, пытается добавить событие, но MyDropDownList имеет значение null, что вызывает исключение. Из того, что я могу сказать, события добавляются (или пытались быть добавленными) до события Load пользовательского элемента управления Selector и, следовательно, также до события LoadDownList.
Любопытно, если я опущу атрибут OnDropDownSelectedIndexChanged в Detail.aspx и вместо этого добавлю следующее в событие Page_Load в Detail.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
RecordSelector1.DropDownSelectedIndexChanged += new EventHandler(RecordSelector1_DropDownSelectedIndexChanged);
}
Работает точно так, как ожидалось. К событиям прилагаются и обрабатываются просто отлично. Нет проблем.
Но это означает несколько плохих вещей:
- Я должен помнить, что не следует использовать конструктор для добавления указанного события в мой пользовательский элемент управления
- Я должен помнить, чтобы не добавлять событие через атрибуты при работе в режиме просмотра исходного кода
- Хуже всего то, что как автор элемента управления мне нужно убедиться, что все остальные, использующие мой элемент управления, знают 1 и 2
Так что я делаю не так? Каждый пример, который я видел до сих пор, показывает аналогичное использование выставления событий дочерних элементов управления через пользовательский элемент управления.