动态添加的UserControl在我点击它时消失了

时间:2012-01-20 03:34:07

标签: c# asp.net webforms

我在UpdatePanel中有像这样的控件

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

选择一个项目后,它会向WidgetAdminControls添加一个新的UserControl WidgetAdminControls.Controls.Add(widget);

然而,当我点击控件是disappers时,我假设因为页面被重建或者某些东西而且它不知道动态添加的UserControl。

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

您是正确的,页面已重建,因此您必须使用每个部分或完整的回发重新创建控制树。

要实现此目的,您必须使页面有状态或包含足够的信息以便在每次往返时重新创建控制树。每种方法都有其优点/缺点。

<强>有状态

有状态页面很可能会使用Session;必须注意不要将太多数据转储到Session中并正确清理(我通常使用管理器来包装Session并管理用户可以同时拥有多少个活动对象)。好处是会话(甚至是在流程外)是非常快速和安全的。

<强>往返

此方法使用ViewState,隐藏字段或URL中的信息。如果页面中包含信息,则应以字节进行测量,即它应该非常小。它也不能免于篡改。

好处是你真的不需要做太多工作,而且没有必要进行清理处理过程。

<强>数据库

或者,您可以在每次单击时将更改保留到数据库并从数据库重建树,但我通常不会喜欢这种方法,除非点击代表一个非常重要的事件且数据已完成且验证

非常简单的例子

这是一个示例,显示使用Session来维护控制树。这应该可以工作,但它不会考虑很多事情,例如用户在同一会话中打开同一页面的另一个副本。管理控制树可能会非常复杂。

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
}

答案 1 :(得分:0)

必须在每次回发时实例化并初始化

Dynamically添加的控件。因此,在这种情况下,您必须在page_init / load事件中加载该控件。