ASP.NET — составной элемент управления — добавление динамического элемента управления после того, как CreateChildControls подавляет событие нажатия кнопки

Настройка. Я хочу, чтобы пользователь ввел данные своих пластиковых карт. Они могут нажать кнопку AddNewCard, чтобы добавить несколько карт.

Код

[Serializable]
public class Card
{
    public string Number { get; set; }
    public string Code { get; set; }
}

public class CardControl : CompositeControl
{
    private LinkButton _lnkAddNewCard = new LinkButton { Text = "Add Card" };
    private  PlaceHolder _plcListCards=new PlaceHolder();

    private IList<Card> _lstCards
    {
        get { return (IList<Card>) ViewState["ListCards"]; } 
        set { ViewState["ListCards"] = value; }         
    } 

    protected override void OnInit(EventArgs e)
    {
        _lnkAddNewCard.Click+=_lnkAddNewCard_Click;
    }

    void _lnkAddNewCard_Click(object sender, EventArgs e)
    {
        var lstCards = _lstCards ?? new List<Card>();
        lstCards.Add(new Card());
        _lstCards = lstCards;
        RenderCard(_lstCards[lstCards.Count - 1]);
    }

    protected override void CreateChildControls()
    {
         Controls.Clear();

         Controls.Add(_lnkAddNewCard);

         Controls.Add(_plcListCards);
         RenderCards();
    }

    protected void RenderCards()
    {
        _plcListCards.Controls.Clear();
        if(_lstCards == null) _lstCards = new List<Card> { new Card() };

        foreach (var card in _lstCards)
            RenderCard(card);
    }

    protected void RenderCard(Card card)
    {
        _plcListCards.Controls.Add(new TextBox() { Text = card.Number});

        _plcListCards.Controls.Add(new TextBox() { Text = card.Code});
    }
}

Проблема

  • При первой загрузке страницы отображаются текстовые поля для первой записи карты.
  • Если пользователь нажимает Добавить новую карточку, происходит обратная передача и срабатывает событие нажатия кнопки.
  • Поскольку это обратная передача, CreateChildControls уже выполняется, поэтому обработчик события нажатия кнопки вызывает RenderCard(), чтобы добавить текстовые поля для записи второй карты.
  • Если пользователь снова нажимает Добавить новую карту, на этот раз нажатие кнопки не срабатывает. БОЛЬШОЕ ПОЧЕМУ?

person EagerToLearn    schedule 04.04.2014    source источник
comment
Маленький ответ на БОЛЬШОЕ ПОЧЕМУ? будут динамические элементы управления, которые необходимо добавлять каждый раз (обратная отправка или отсутствие обратной отправки), прежде чем событие, связанное с ними, может сработать. Как добавить составной элемент управления на страницу?   -  person Shashank Chaturvedi    schedule 07.04.2014
comment
Я не могу воспроизвести проблему. Я создал новый проект веб-приложения, добавил ваш класс CardControl (с небольшими правками) и создал веб-форму с разметкой <form id="form1" runat="server"> <uc:CardControl runat="server" ID="cardControl" /> </form>. Нажатие «Добавить карту» каждый раз добавляет два дополнительных текстовых поля.   -  person Michael Liu    schedule 12.04.2014


Ответы (2)


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

var newCard = new Card();
newCard.Click+=_lnkAddNewCard_Click;
_lstCards.Add(new newCard);
person Josh    schedule 04.04.2014
comment
кто сказал, что у карты есть какое-либо событие Click. пожалуйста, просмотрите код - person EagerToLearn; 05.04.2014

ты должен позвонить

_lnkAddNewCard.Click+=_lnkAddNewCard_Click;

в каждом посте назад, поэтому для _lnkAddNewCard_Click будет

void _lnkAddNewCard_Click(object sender, EventArgs e)
{
    _lnkAddNewCard.Click+=_lnkAddNewCard_Click;
    var lstCards = _lstCards ?? new List<Card>();
    lstCards.Add(new Card());
    _lstCards = lstCards;
    RenderCard(_lstCards[lstCards.Count - 1]);
}
person Bakri    schedule 09.04.2014