我遇到了同样的问题。问题是您需要在 OnInit 阶段之前添加脚本管理器 - 据我所知,它需要在 preinit 阶段完成。您可以通过添加大量覆盖来看到这一点 - 我发现页面通过了 preinit ok,然后转到 addedcontrol 事件,它在(或之后,但这一点是有道理的)“你需要一个脚本管理器“被抛出。我正在努力寻找如何从子用户控件向 Page.PreInit 事件添加事件处理程序,因为 WUC 没有 PreInit 事件。甚至 WUC 构造函数在此之前也不会触发,并且在构造函数中页面对象为空,因此您无法将其添加到那里。即使在 WUC 的 AdditionalControl 阶段,您似乎仍然无法访问主页( ScriptManager oSCM = ScriptManager. 获取当前(页面);返回 null),因此您似乎无法在引发错误之前添加脚本管理器(如果需要)。
/edit:- 据我所见(我在 asp.net 论坛上对此没有任何答案 - 令人惊讶,令人惊讶)WUC 直到父级的预初始化阶段之后才开始执行它的方法/事件,所以有两种方法可以做到这一点。
1)我认为我会这样做的方式是不要将任何内容放在需要脚本管理器的设计器中,并将占位符放在需要这些内容的地方。然后在 wuc 加载中使用 ScriptManager.GetCurrent 查看是否已经存在一个,如果没有则创建它。然后动态添加需要 SCM 的内容。像这样的东西: -
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="wucTestExample.ascx.cs" Inherits="wucTestExample" %>
<asp:PlaceHolder ID="plcAJAX" runat="server" />
<asp:Label ID="lblGeneral" runat="server" Text="这是另一个标签" />
----------------后面的代码---------------
使用系统;
使用 System.Collections.Generic;
使用 System.Linq;
使用 System.Web;
使用 System.Web.UI;
使用 System.Web.UI.WebControls;
公共部分类 wucTestExample : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager oSCM = ScriptManager.GetCurrent(this.Page);
如果(oSCM == null)
{
oSCM = new ScriptManager();
oSCM.ID = "scmAJAX";
oSCM.EnablePartialRendering = true;
this.plcAJAX.Controls.AddAt(0, oSCM);
}
更新面板 udpMain = 新的更新面板();
udpMain.ID = "udpMain";
文本框 txtMain = new TextBox();
txtMain.ID = "txtMain";
// 这里的其他属性
按钮 btnPostback = new Button();
btnPostback.ID = "btnPostback";
btnPostback.Click += new EventHandler(btnPostback_Click);
btnPostback.Text = "部分回发";
标签 lblPostback = new Label();
lblPostback.ID = "lblPostback";
lblPostback.Text = "初始回发";
udpMain.ContentTemplateContainer.Controls.Add(txtMain);
udpMain.ContentTemplateContainer.Controls.Add(btnPostback);
udpMain.ContentTemplateContainer.Controls.Add(lblPostback);
this.plcAJAX.Controls.Add(udpMain);
}
void btnPostback_Click(对象发送者,EventArgs e)
{
// 这里实现按钮代码
标签 lblPostback = (Label)this.plcAJAX.FindControl("lblPostback");
if (lblPostback != null)
{
lblPostback.Text = String.Format("WUC POstback at : {0}", DateTime.Now.ToLongTimeString());
}
}
}
然后这样使用它:-
<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="TestExampleNoSCM.aspx.cs" Inherits="TestExampleNoSCM" %>
<%@ Register Src="~/wucTestExample.ascx" TagName="wucTestExample" TagPrefix="ucTE" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:内容>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<%--<asp:ScriptManager ID="scmAJAX" runat="server" />--%>
<asp:标签 ID="lblLoadTime" runat="server" />
<ucTE:wucTestExample ID="wucTestExample" runat="server" />
</asp:内容>
----------------后面的代码---------------
使用系统;
使用 System.Collections.Generic;
使用 System.Linq;
使用 System.Web;
使用 System.Web.UI;
使用 System.Web.UI.WebControls;
公共部分类 TestExampleNoSCM : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.lblLoadTime.Text = String.Format("页面加载时间:{0}",DateTime.Now.ToLongTimeString());
}
}
因此,如果您在父页面中评论或取消评论 SCM,WUC 仍然可以正常工作。
2)我看到了另一个需要更新面板的选项,程序员在设计器中创建了所有控件,然后在页面加载中循环它们(在创建 SCM 之后,如果需要,以及 UDP 并添加所有控件在 WUC UDP 上,然后将其添加到占位符,但这让我觉得相当危险,因为它似乎是双重实例化控制,我认为它可能会回来咬他们的屁股......
方法 1 的缺点是,以编程方式在更新面板中创建所有内容需要更多工作,但如果你真的想构建一个独立的 WUC,这似乎是你的代价(希望 WUC 不应该那么复杂,反正)。就个人而言,我认为在我的应用程序中(因为 WUC 不会在它之外使用)我会确保在主页上需要的地方添加 SCM。
另一个,最后,我要注意 - 我看到人们说“将它添加到母版页” - 这似乎是一个特别糟糕的主意,恕我直言,除非你的应用程序中的每个页面都需要 SCM,因为它会添加您的页面出现了全新的膨胀程度,这似乎不是一个好主意,因为 ASP.NET 似乎已经有了很好的膨胀程度......