我遇到了同樣的問題。問題是你需要在OnInit階段之前添加腳本管理器 - 就我所見,它需要在初始階段完成。你可以通過加載一個覆蓋來看到這一點 - 我發現頁面通過預置好了,然後去了addedcontrol事件,它在(或剛好在這之後,但這點有道理),「你需要一個腳本管理器「被拋出。我正在努力尋找如何從兒童用戶控件向Page.PreInit事件添加事件處理程序,因爲WUC沒有PreInit事件。即使WUC構造函數在該點之前也不會觸發,並且在構造函數中頁面對象爲null,因此您無法將其添加到此處。即使在WUC的AddedControl階段,您似乎仍然無法訪問主頁面(ScriptManager oSCM = ScriptManager.GetCurrent(Page);返回null),所以如果您似乎無法添加腳本管理器需要,在錯誤被拋出之前。據我所知(在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="This is another label" />
----------------code behind---------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class wucTestExample : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager oSCM = ScriptManager.GetCurrent(this.Page);
if (oSCM == null)
{
oSCM = new ScriptManager();
oSCM.ID = "scmAJAX";
oSCM.EnablePartialRendering = true;
this.plcAJAX.Controls.AddAt(0, oSCM);
}
UpdatePanel udpMain = new UpdatePanel();
udpMain.ID = "udpMain";
TextBox txtMain = new TextBox();
txtMain.ID = "txtMain";
// other attrbutes here
Button btnPostback = new Button();
btnPostback.ID = "btnPostback";
btnPostback.Click += new EventHandler(btnPostback_Click);
btnPostback.Text = "Partial Postback";
Label lblPostback = new Label();
lblPostback.ID = "lblPostback";
lblPostback.Text = "initial postback";
udpMain.ContentTemplateContainer.Controls.Add(txtMain);
udpMain.ContentTemplateContainer.Controls.Add(btnPostback);
udpMain.ContentTemplateContainer.Controls.Add(lblPostback);
this.plcAJAX.Controls.Add(udpMain);
}
void btnPostback_Click(object sender, EventArgs e)
{
// implement button code here
Label 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:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<%--<asp:ScriptManager ID="scmAJAX" runat="server" />--%>
<asp:Label ID="lblLoadTime" runat="server" />
<ucTE:wucTestExample ID="wucTestExample" runat="server" />
</asp:Content>
----------------code behind---------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class TestExampleNoSCM : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.lblLoadTime.Text = String.Format("Page load at: {0}",DateTime.Now.ToLongTimeString());
}
}
所以,如果你對此有何評論或父頁面取消對SCM,世維會仍然仍然可以正常工作。
2)我看到了另一個選項,需要更新面板,程序員在設計器中創建所有控件,然後在頁面加載時環繞它們(在創建SCM之後(如果需要的話)以及UDP和在WUC UDP中添加了所有的控件,然後將其添加到佔位符中,但這樣做會讓我感到非常危險,因爲它似乎是雙重實例化的控件,我想它可能會回來咬他們的屁股。
方法1的缺點是更多的工作是以編程方式在您的updatepanel中創建所有內容,但是如果您確實想要構建一個自我依賴的WUC,那似乎是您的價格(並且希望WUC不應該無論如何,這是複雜的)。我個人認爲在我的應用程序中(因爲WUC不會被使用)我會確保在主頁面上添加所需的SCM。
另外一個,最後,注意我會全情 - 我見過的人說:「把它添加到母版頁」 - 這似乎是一個特別糟糕的主意,恕我直言,除非每頁在您的應用程序的需求因爲它會給你的頁面增加一個全新的膨脹水平,並且這似乎不是一個好主意,因爲ASP.NET似乎已經具有良好的膨脹水平...
只是一方不是,代碼有點「雙」。您重寫OnInit方法並添加一個Init事件處理程序。只需將Page_Init中的代碼放入覆蓋的OnInit? – Colin 2009-07-09 16:50:31