Vittorio Romeo
Vittorio Romeo

Reputation: 93304

Usercontrol that dynamically generates a list of controls on postback

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?

Upvotes: 1

Views: 788

Answers (1)

Mir
Mir

Reputation: 86

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
        }
    }  

Upvotes: 1

Related Questions