Как присвоить значение элементу базовой страницы из Page_Load дочерней страницы?

#c# #asp.net #inheritance

#c# #asp.net #наследование

Вопрос:

Вероятно, я не первый, у кого возникает эта проблема, но я не могу найти такой вопрос и решение для него.

У меня есть базовая страница в формате aspx и дочерняя страница, которая наследуется от базовой страницы. Из Page_Load метода дочерней страницы я вызываю метод на базовой странице, подобный base.SetLiteral(value) , который обращается к литералу, определенному на базовой странице. Я получаю исключение NullReferenceException, поскольку литерал равен null.

Вероятно, это связано с жизненным циклом страницы, поскольку элементы управления базовой страницы на этом этапе еще не созданы.

Как я могу это сделать?

Редактировать

Вот трассировка стека исключения. Мне это ничего не говорит.

 System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object.
Source=PageInheritance
StackTrace:
   at PageInheritance.BasePage.SetLiteral(String value) in D:crap-projectsPageInheritanceBasePage.aspx.cs:line 17
   at PageInheritance.Page1.Page_Load(Object sender, EventArgs e) in D:crap-projectsPageInheritancePage1.aspx.cs:line 13
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:  
  

Комментарии:

1. Можете ли вы опубликовать несколько верхних строк трассировки стека? Является base нулевым? или исключение nullreferenceexception генерируется изнутри метода SetLiteral?

2. Обязательно ли это делать Page_Load? Если вы делаете это предварительно, все элементы управления должны быть инициализированы.

3. @Connell Watkins base не равен null, исключение генерируется внутри SetLiteral метода, когда я делаю MyLiteral.Text = value

4. MyLiteral вероятно, он еще не инициализирован. Посмотрите на ответ @Connell Watkins для получения информации о жизненном цикле страницы.

Ответ №1:

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

Взгляните на ASP.NET Обзор жизненного цикла страницы — События жизненного цикла, если вы еще этого не сделали. Как вы можете видеть, это должно работать в Page_Load , и я действительно не понимаю, в чем проблема. Попробуйте перенести событие на более поздний этап жизненного цикла страницы, такой как событие loadComplete.

Комментарии:

1. Пытался сделать это из дочерней предварительной загрузки и loadComplete , не помогает, та же проблема

2. Если элемент управления не был загружен методом loadComplete, что-то еще идет не так. Find all references на MyLiteral элементе управления и нажмите точку останова в строке, которая задает переменную. Посмотрите на стек вызовов при достижении точки останова.

3. Я отредактировал вопрос и добавил трассировку стека, мне это не помогает, может быть, вам что-нибудь скажут. Спасибо

Ответ №2:

Хорошо, похоже, что когда кто-то наследует страницу .aspx, наследуется только код, за которым стоит. Разметка (.aspx сама по себе) не наследуется, и нет способа (например, ContentPlaceHolder на главной странице) определить, какие элементы (из производной, базовой страницы или обоих) нужно разместить на странице результатов.

Поскольку страница base .aspx не наследуется, никакие элементы управления, добавленные к ней в конструкторе, никогда не инициализировались. Я не совсем понимаю, как это работает (вызывается Page_Init, но то, как страница решает не инициализировать свои элементы управления, остается загадкой) Кто-нибудь может объяснить этот момент?

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

Если я где-то ошибаюсь, пожалуйста, дайте мне знать.

Редактировать

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

P.S.

Я нашел способ наследовать страницу .aspx с разметкой на базовой странице здесь: http://www.codeproject.com/KB/aspnet/page_templates.aspx но для меня это выглядит как полный хакерство.

Ответ №3:

Что-то здесь не так, но если это так, вы могли бы попробовать создать обработчик событий на базовой странице, который запускается после инициализации элементов управления:

На базовой странице:

 public event EventHandler BasePageInitialized;

protected void Page_Load(object sender, EventArgs e)
{
    if (this.BasePageInitialized != null)
        this.BasePageInitialized(this, e);
}
  

На дочерней странице:

 protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
        base.BasePageInitialized  = new EventHandler(Base_Initialized);
}

protected void Base_Initialized(object sender, EventArgs e)
{
    base.SetLiteral(value)
}
  

Комментарии:

1. Пробовал это, Base_Initialized никогда не вызывается. Более того, если я попытаюсь добавить обработчик в дочернюю Page_Load базу Page_Load , он никогда не вызывается. Если я добавлю обработчик в детской Page_LoadComplete , базы Page_Load называется, но Base_Initialized не вызывается в любом случае.

Ответ №4:

Я не уверен, применимо ли это к вашей проблеме, но вы могли бы создать класс, и обе страницы унаследовали бы от одного и того же класса, который, в свою очередь, унаследует от basic System.Web.UI.Page . Вы можете поместить общий метод в новый класс, и он будет доступен с обеих страниц.

Комментарии:

1. У меня есть несколько страниц, которые наследуются от базовой страницы. Метод доступен в полном порядке, элементы управления базовой страницы еще не созданы, когда я их вызываю.