2010-10-13 2 views
0

Я знаком с созданием и сохранением динамических элементов управления при первой загрузке страницы и последующих обратных передачах, но у меня возникают проблемы со следующими инициированной пользователем сценарий ...Как добавить постоянные динамические элементы управления, основанные на пользовательском вводе (не на начальной загрузке страницы)

в моей демо у меня есть заполнитель, две кнопки и буквального

<div> 
    <asp:PlaceHolder ID="phResponses" runat="server" /> 
</div> 
<div> 
    <asp:Button ID="btnAdd" Text="Add" runat="server" OnClick="Add"/> 
    <asp:Button ID="btnInspect" Text="Inspect" runat="server" OnClick="Inspect"/> 
</div> 
<div> 
    <asp:Literal ID="litResult" runat="server"/> 
</div> 

Я хочу, чтобы пользователь мог нажать на кнопку добавить, чтобы дать ответ, так что я имеют ...

protected void Page_Init(object sender, EventArgs e) 
{ 
    BuildControls(); 
} 

protected void Add(object sender, EventArgs e) 
{ 
    BuildControls(); 
} 

protected void BuildControls() 
{ 
    phResponses.Controls.Add(new LiteralControl { ID = "response_" + _Count.ToString() }); 
    _Count++; 
} 

_Count - это статическая переменная-член, позволяющая мне иметь уникальные идентификаторы для новых элементов управления. Я понимаю, что мне нужно перестроить динамические элементы управления на странице Page_Init, но проблема в том, что я получаю 2 новых элемента управления Literal при каждой обратной передаче. Также, если какое-либо свойство Text помещается в новые элементы управления, оно теряется, когда элементы управления перестраиваются.

Как я могу избежать добавления нескольких элементов управления и как сохранить новые свойства при перестройке этих элементов управления?

Я использую следующие для проверки ответов

protected void Inspect(object sender, EventArgs e) 
{ 
    foreach (var control in phResponses.Controls) 
    { 
     if (control is LiteralControl) 
     { 
      litResults.Text += "<p>" + control.Text + " : " + control.ID + "</p>"; 
     } 
    } 
} 

который сам добавляет еще один нежелательный контроль из-за переустройство на Page_Init

ответ

0

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

  1. Добавить новый private bool _isControlsBuilt = false;.
  2. Изменить Page_Init, чтобы проверить _isControlsBuilt перед тем, как позвонить BuildControls.
  3. _isControlsBuilt до true в пределах BuildControls.
  4. Удостоверьтесь, что BuildControls встречается раньше в page lifecycle, чем Page_Init.

Что касается потери значений элементов управления при обратной передаче, это будет то, что они никогда не попадают в viewstate. Я не уверен, если это было бы работать, но мое первое предположение было бы, чтобы добавить строку в конец BuildControls позвонить Page.RegisterRequiresControlState:

protected void BuildControls() 
{ 
    LiteralControl newLiteral = new LiteralControl { ID = "response_" + _Count }; 
    this.RegisterRequiresControlState(newLiteral); 
    phResponses.Controls.Add(newLiteral); 

    _Count++; 
    _isControlsBuilt = true; 
} 

Если это не работает (что может означать, что это _view_state, а не _control_state, что важно для вас здесь), вам, возможно, придется посмотреть, как перевернуть свой собственный viewstate. Я написал о том, как это сделать в my answer to #3854193, что может показаться вам полезным.