简体   繁体   中英

Dynamically Added UserControl disappears when I click on it

I have controls inside a UpdatePanel like this

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        Step 1 (Choose a Widget to Manage)<br />
        <asp:DropDownList ID="DropDownWidgetSelection" runat="server"  
            OnSelectedIndexChanged="DropDownWidgetSelection_SelectedIndexChanged" 
            AutoPostBack="True">
        </asp:DropDownList>
        <div id="WidgetAdminControls" runat="server"></div>
    </ContentTemplate>
</asp:UpdatePanel>

When an Item is selected, it will add a new UserControl to WidgetAdminControls WidgetAdminControls.Controls.Add(widget);

However, when I click on the control is disappers, I assume because the page is rebuilt or somehting and it does not know about the dynamically added UserControl.

How do I fix this problem?

You are correct, the page is rebuilt, thus you must recreate the control tree with every partial or complete postback.

To accomplish this, you must make your page stateful or include enough information to recreate the control tree with every roundtrip. Every approach has its advantages/disadvantages.

Stateful

Most likely a stateful page will use Session; care must be taken not to dump too much data into Session and to cleanup properly (I usually use a manager to wrap Session and manage how many active objects a user can have at once). The upside is that Session (even out of process) is very fast and secure.

Roundtrip

This approach uses ViewState, hidden fields, or information in the URL. If information is included with the page, it should be measured in bytes , ie it should be extremely small. It is also not immune to tampering.

The upside is that you really don't have to do much to make this work, and there is no disposition process needed to cleanup.

Database

Alternatively, you could persist your changes to a database with every click and rebuild the tree from the database, but I'm not usually not a fan of this approach unless the click represents a very significant event and the data is complete and validated.

Very Simple Example

Here is an example showing the use of Session to maintain a control tree. This should work but it doesn't account for many things, such as the user opening another copy of the same page in the same session. Managing control trees can get quite complex.

private List<string> _listOfStrings
{
   get
   {
     return (List<string>)Session["_listOfStrings"];
   }
   set
   {
     Session["values"] = value;   
   }
}

protected override OnInit( EventArgs e )
{
    if( !Page.IsPostback )
    {
        _listOfStrings = new List<string>();
    }

    BuildControlTree();
}

private void BuildControlTree()
{
   foreach( string s in _listOfStrings )
   {
     // add a control to the control tree
   }
}

protected void btnAddItem_Click( object sender, EventArgs e )
{
    _listOfStrings.Add( "some new item" );

    // insert the control into the tree
}

Dynamically added controls must be instantiated and initialized on each postback. So in this case you have to load that control in page_init/load event.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM