当我点击它时,动态添加的UserControl就会消失

本文关键字:添加 UserControl 消失 动态 | 更新日期: 2023-09-27 18:20:55

我在类似的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添加一个新的UserControlWidgetAdminControls.Controls.Add(widget);

然而,当我点击控件时,我认为这是因为页面已经重建或正在处理,并且它不知道动态添加的UserControl。

如何解决此问题?

当我点击它时,动态添加的UserControl就会消失

您是正确的,页面是重新生成的,因此您必须在每次部分或完整回发时重新创建控制树。

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

有状态

有状态的页面很可能会使用Session;必须注意不要将太多数据转储到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
}
动态添加的控件必须在每次回发时实例化和初始化。因此,在这种情况下,您必须在page_init/load事件中加载该控件。