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

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

В моей демонстрации у меня есть заполнитель, две кнопки и литерал

<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


person Nick Allen    schedule 13.10.2010    source источник


Ответы (1)


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

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

Что касается потери значений элементов управления при обратной передаче, то они никогда не попадут в состояние просмотра. Я не уверен, что это сработает, но я бы предпочел добавить строку в конец 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), вам, возможно, придется посмотреть на изменение собственного состояния просмотра. Я написал о том, как это сделать, в мом ответе на #3854193, который может быть вам полезен.

person Owen Blacker    schedule 13.10.2010