2

Setup - I want user to enter details for their plastic cards. They can click on AddNewCard button to add multiple cards.

Code

[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});
    }
}

Issue

  • On first Page Load, Textboxes for first Card entry are shown.
  • If user clicks on Add New card, postback happens and button click event fires.
  • As it's a postback, CreateChildControls has executed already, so, button click event handler calls RenderCard() so as to append textboxes for second card entry.
  • If user clicks Add New card again, button click doesn't fire this time. A BIG WHY?
Michael Liu
  • 52,147
  • 13
  • 117
  • 150
EagerToLearn
  • 827
  • 2
  • 14
  • 24
  • The small answer to "A BIG WHY?" would be dynamic controls need to be added every time (post back or no post back) before the event related to them could fire. How do you add your composite control to the page? – Shashank Chaturvedi Apr 07 '14 at 18:17
  • I can't reproduce the problem. I created a new Web application project, added your CardControl class (with a few minor edits), and created a WebForm with the markup `
    `. Clicking "Add Card" adds two additional text boxes each time.
    – Michael Liu Apr 12 '14 at 18:15

2 Answers2

0

The new card hasn't had any subscription to the click event created. You need to add an event handler each time you create a new card.

var newCard = new Card();
newCard.Click+=_lnkAddNewCard_Click;
_lstCards.Add(new newCard);
Josh
  • 10,352
  • 12
  • 58
  • 109
0

you have to call

_lnkAddNewCard.Click+=_lnkAddNewCard_Click;

in each post back so for _lnkAddNewCard_Click will be

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]);
}
Bakri
  • 597
  • 10
  • 22