动态创建ASP.NET Web用户控件包含AJAX Extender抛出错误“在PreRender之后可能无法注册Extender控件”

时间:2012-08-10 16:50:28

标签: asp.net web-applications asp.net-ajax

我正在尝试动态添加一个Web用户控件,当用户单击按钮时,该控件包含一个带有Gridview的AJAX可折叠面板。我能够添加一个用户控件的实例,但是当我添加其他用户控件时,它会抛出以下错误:

  

描述:执行期间发生了未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

异常详细信息:System.InvalidOperationException:Extender控件   可能不会在PreRender之后注册。

     

来源错误:

     

执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

我是ASP.NET开发的新手,我用来处理回发的方法是将用户控件存储在列表中,并在prerender方法调用中再次添加它们。我不知道该怎么做或者我是否正确处理用户控件的创建。任何建议都表示赞赏。

这是后端代码:

public partial class Test : System.Web.UI.Page
{
    private IList<Control> _persistedControls;
    private const string PersistedControlsSessionKey = "thispage_persistedcontrols";

static int count = 1;
private IList<Control> PersistedControls()
{
    if (_persistedControls == null)
    {
        if (Session[PersistedControlsSessionKey] == null)
            Session[PersistedControlsSessionKey] = new List<Control>();
        _persistedControls = Session[PersistedControlsSessionKey] as IList<Control>;
    }
    return _persistedControls;
}

protected void Page_Load(object sender, EventArgs e)
{
    PersistedControls();
}

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);
    IList<Control> controlsToGenerate = PersistedControls();

    // regenerate dynamically created controls
    foreach (var control in controlsToGenerate)
    {
        MasterPanel.Controls.Add(control);
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    Control control = LoadControl("~/WebUserControl/UseCaseSetupUserControl.ascx");
    control.ID = "uc" + count++.ToString();
    MasterPanel.Controls.Add(control);
    _persistedControls.Add(control);
    MasterPanel.Controls.Add(new LiteralControl("<br />"));
    _persistedControls.Add(new LiteralControl("<br />"));  
}

}

这是ASPX代码:

   <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
        <div>    
            <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
            <br />
            <asp:Panel ID="MasterPanel" runat="server">
            </asp:Panel>    
        </div>
    </form>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

在页面生命周期中尽早创建控件。

由于您已加载PersistedControls,因此应将其添加到控件集合中。在Init中添加控件的最佳位置。

如果你真的不能那样做,那就用Load

如果必须对某个事件进行此操作,那么您可以在第一时间添加该控件,但是要保留它并记住在下一个回发之后将其添加回 Init或Load

如果您在PreRender之后添加控件,则无法将任何数据添加到ViewState。 SaveViewState发生在PreRender之前。许多控件严重依赖ViewState来正常运行。例外情况只是告诉您应该在页面生命周期中添加控件。