1

I want to create a reusable user control that allows the user to create and remove tags.

It should have a textbox where the user can enter a tag name, and a button to submit the tag.

After sumbitting the tag, it should dynamically create a label with the tag name with a "X" button to remove it for every entered tag.

Something like this:

[ Textbox ] [Submit]

[X] Tag 1
[X] Tag 2
[X] Tag 3

The issue is that I cannot figure out how to make everything work properly.


Selector.ascx

< markup for the textbox >
< markup for the sumbit button >
<asp:Placeholder runat="server" ID="PHList" />

I'm using an asp:Placeholder to generate the dynamic controls.


Selector.ascx.cs

I need to keep track of the generated controls between postbacks.

I'm using a List<string> stored in the viewstate:

private List<string> SelectedTags
{
    get
    {
        return (List<string>) ViewState["SelectedTags"];
    }
    set { ViewState["SelectedTags"] = value; }
}

When I click the submit button, I add a new tag to the SelectedTags list, and call the RefreshPlaceholder function:

void RefreshPlaceholder()
{
    PHList.Controls.Clear();
    foreach(var x in SelectedTags) 
    {
         // generate a label and the "X" button, wiring it with a lambda
    }
}

When I click the submit button, a new (button, label) pair is correctly generated and displayed after postback.

When I click any of the generated "X" buttons, however, I get an error because the click event fired by the dynamically generated button cannot find the sender button anymore, since it hasn't been generated yet.

If I try to generate the buttons in OnLoad, the same issue occurs, as postback events occur before Page.Load.

If I try to generate the buttons in OnInit, the ViewState has not been updated yet, so the generated list will be outdated as the SelectedTags viewstate list is not yet updated.

I can't seem to find a solution to make everything work as intended. What am I doing wrong?

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416

1 Answers1

1

Declare a List of type Buttons on OnInit method; then in RefreshPlaceHolder retrieve and loop through selected tags and add them to the List

protected override void OnInit(EventArgs e)
        {

               List<Button> listButtons ;

            base.OnInit(e);
        }  



 void RefreshPlaceholder()
    {
        listButtons = new List<Button>();
        PHList.Controls.Clear();
        foreach(var x in SelectedTags) 
        {
         Button b = new Button();
         b.Text=x;
         listButtons.add(b);



       // generate a label and the "X" button, wiring it with a lambda
        }
    }  
Mir
  • 86
  • 6
  • You can ofcourse then loop the button list to display it on the page on some user event – Mir Dec 23 '14 at 11:24