I am hitting this same problem. The problem is that you need to add the scriptmanager before the OnInit stage - as far as I can see it needs to be done at the preinit stage. You can see this by adding a load of overrides - I found the the page got through the preinit ok, then went to the addedcontrol event and it was at (or just after, but this point makes sense) that the "You need a scriptmanager" gets thrown. I am struggling to find how to add an event handler to the Page.PreInit event from a child usercontrol as the WUCs don't have a PreInit event. Even the WUC constructor doesn't fire before that point and in the constructor the page object is null so you can't add it there. Even at the AddedControl stage of the WUC, you still don't seem to be able to access the main page ( ScriptManager oSCM = ScriptManager.GetCurrent(Page); returns null) so you can't seem to add the scriptmanager, if you need to, before the error is thrown.
/edit:-
As far as I can see it (and I've had no answer to this on the asp.net forums - surprise, surprise) the WUC doesn't start kicking in it's methods/events until after the parent's preinit stage, so there's 2 ways of doing this.
1) The way I think I would do this is to not put any content in the designer that requires the scriptmanager and to put placeholders where such content needs to go. Then in the wuc load you use the ScriptManager.GetCurrent to see if there's one already there and then create it if not. Then you dynamically add the content that requires the SCM. Something like this:-
<%@ 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());
}
}
}
then use it thus:-
<%@ 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());
}
}
So if you comment or uncomment the SCM in the parent page, the WUC still works either way.
2) I've seen another option where an update panel was needed and the programmer created all the controls in the designer and then looped round them in the page load (after creating the SCM, if needed, and the UDP and added all the controls on the WUC UDP, before then adding that to to placeholder, but this strikes me as rather dangerous as it seems to be double-instantiating control, and I think it may come back to bite them on the bum...
The downside with method 1 is that it's more work to create everything in your updatepanel programmatically, but if you really want to build a self-dependent WUC, that seems to be your price (and hopefully, the WUC shouldn't be that complicated, anyway). Personally, I think in my app (as the WUC won't be used outside it) I'll just make sure I add in an SCM where needed on the main page.
One other, final, note I would pitch in - I've seen people saying "add it to the master page" - this seems to be a particularly bad idea, IMHO, unless every page in your app needs the SCM as it will add a whole new level of bloat to your pages, and that doesn't seem to be a good idea as ASP.NET seems to have a good level of bloat already...