Управление сервером и состояние просмотра - PullRequest
1 голос
/ 08 декабря 2008

Хорошо, пришло время показать мое полное отсутствие знаний для всех веб-форм вещей, но здесь идет. Я расширяю элемент управления Panel и OnPreRender, добавив в него некоторые дополнительные элементы управления (для простоты просто скажем 1 текстовое поле). Отсюда я просто позволяю методу Panels Render делать свое дело.

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

Я хочу вставить туда текстовое поле при первой загрузке и перезагружать их из кешей control / viewstate. В этом случае в моем примере просто вставляем одно текстовое поле на панель, если значение текстового поля изменяется и происходит обратная передача, я хочу, чтобы это значение оставалось измененным значением.

Действительно базовые веб-формы, которые я знаю, но мне никогда не приходилось создавать собственные элементы управления в свое время. Любая помощь приветствуется.

Крис.

Ответы [ 4 ]

3 голосов
/ 08 декабря 2008

Вам необходимо (заново) создать дочерний элемент управления (текстовое поле) в OnInit - чтобы он был там, когда вызывается LoadViewState и ProcessPostBackData.

Подробнее см. Жизненный цикл управления сервером 1004 *.

1 голос
/ 08 декабря 2008

Не уверен, применимо ли это ко всем версиям .Net (я думаю, что 2.0 или более поздняя версия), но есть метод CreateChildControls, который на самом деле не является частью жизненного цикла, он в основном вызывается каждый раз, когда вызывается метод EnsureChildControls , По умолчанию он вызывается перед PreRender, если это не постбэк. Так что в основном ваш код будет выглядеть так:

public class SomeControl : WebControl, INamingContainer
{
  private TextBox someTextBox;

  protected override void CreateChildControls()
  {
    base.CreateChildControls();

    someTextBox= new TextBox();
    someTextBox.ID = "tbxMain";

    Controls.Add(textboxToCheck);
  }
}

Теперь нужно не принимать во внимание то, что, если вы не вызовете EnsureChildControls, вы не можете быть на 100% уверены, что элементы управления существуют до того, как публичные свойства вашего элемента управления будут заполнены загрузкой ViewState. Что это значит? Хорошо, возьмите код из ранее и добавьте свойство для CssClass:

public class SomeControl : WebControl, INamingContainer
{
  private TextBox someTextBox;

  protected override void CreateChildControls()
  {
    base.CreateChildControls();

    someTextBox= new TextBox();
    someTextBox.ID = "tbxMain";

    Controls.Add(textboxToCheck);
  }

  public String CssClass { get; set; }
}

В CreateChildControls вы не захотите этого:

someTextBox.CssClass = CssClass;

Поскольку нет никакого способа убедиться, что контроль еще существует. Есть несколько способов справиться с этим:

public String CssClass { получить { EnsureChildControls (); return someTextbox.CssClass; }

 set
 { 
   EnsureChildControls();
   someTextbox.CssClass = value;
 }

В этом примере я вызываю EnsureChildControls (при условии, что вы устанавливаете CssValue для текстового поля в методе CreateChildControls) и устанавливаете или получаете из текстового поля.

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

protected override void OnPreRender(EventArgs e)
{
  someTextbox.CssClass = CssClass;
}

Таким образом можно избежать беспокойства о том, что свойство заполняется уже во время загрузки ViewState.

Одно примечание:

Использование INamingContainer может быть важным. По сути, все, что нужно, - это убедиться, что элементы управления родительского элемента управления имеют уникальный идентификатор на странице, применяя имя родителя (и, возможно, больше) к идентификатору. В основном, если идентификатор родительского элемента равен Parent, а идентификатор дочернего элемента управления - Child, этот идентификатор может отображаться как Parent_Child. Это решит проблемы с ViewState, не заполняющим свойства правильно или не заполненными вообще.

1 голос
/ 08 декабря 2008

Динамические элементы управления в ASP.NET сложны, особенно если вы новичок в веб-формах и жизненном цикле страницы. Если вы можете избежать динамического контроля, сделайте это. Вместо этого используйте controlName.Visible = false и другие приемы.

Если вам необходимо прочитать эту статью . Основное правило: добавляйте элементы управления в начале жизненного цикла страницы, ссылайтесь на них позже в жизненном цикле страницы. PreRender - почти самый конец, необычное место для добавления и использования элементов управления.

0 голосов
/ 08 декабря 2008

Внутри вашего кода вам нужно будет управлять восстановлением информации о состоянии просмотра, если вам нужны сервисы просмотра состояния.

Вот хороший пример: Пример состояния просмотра от Microsoft. В примере кода есть несколько других элементов, на которые вы ссылаетесь, но это должно привести вас к правильному пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...