Это сообщение в блоге очень хорошо описывает проблему, а также предлагает решение.Я могу подтвердить, что решение работает, и я повторю соответствующие части здесь:
Проблема
У нас есть пользовательский элемент управления и инициализируем его элемент управления в Init
событие, чтобы оно было готово, когда ViewState
восстановлен (между Init
и Load
).
Как только вы начнете использовать эту технику инкапсуляции, у вас не будет много времени, пока выхотите передать параметр, который влияет на данные, которые вы загружаете.Прежде чем мы это сделаем, мы должны знать, что событие Init
происходит в обратном порядке.То есть дочерние элементы управления запускают свое событие Init
до того, как это событие будет запущено для родительского элемента.Таким образом, событие Page.Init
слишком поздно для нас, чтобы устанавливать какие-либо свойства для элементов управления.
Естественное решение состоит в том, чтобы попытаться использовать событие Page.PreInit
, однако, когда вы это делаете, вы часто найдетечто все ваши контрольные ссылки null
.Это происходит, когда ваша страница реализована с использованием главной страницы, и это относится к тому, как реализованы главные страницы.Элементы управления <asp:ContentPlaceHolder />
на главной странице используют интерфейс ITemplate
для создания своего содержимого.Этот контент (дочерние элементы управления) обычно не готовится до тех пор, пока не будет вызвано событие Init
, что означает, что ссылки на элементы управления недоступны.Для нас это проблема.
Решение
Исправление удивительно просто;все, что нам нужно сделать, это прикоснуться к свойству Master
в нашем Page
, и это заставит элементы управления стать доступными.Если мы используем вложенные главные страницы, нам нужно прикоснуться к каждой главной странице в цепочке.
Затем автор сообщения блога предлагает небольшой фрагмент кода, который можно выполнить в обработчике PreInit
.вашего Page
, который использует MasterPage
и содержит пользовательский элемент управления:
protected override void OnPreInit(EventArgs e)
{
// Walk up the master page chain and tickle the getter on each one
MasterPage master = this.Master;
while( master != null ) master = master.Master;
// Access now initialized user control
ucAddress.City = "Dallas";
}