Can't get ScriptManager.RegisterStartupScript in WebControl nested in UpdatePanel to work

Chris picture Chris · Apr 29, 2009 · Viewed 107.4k times · Source

I am having what I believe should be a fairly simple problem, but for the life of me I cannot see my problem. The problem is related to ScriptManager.RegisterStartupScript, something I have used many times before.

The scenario I have is that I have a custom web control that has been inserted into a page. The control (and one or two others) are nested inside an UpdatePanel. They are inserted onto the page onto a PlaceHolder:

<asp:UpdatePanel ID="pnlAjax" runat="server">
  <ContentTemplate>
    <asp:PlaceHolder ID="placeholder" runat="server">
    </asp:PlaceHolder>
    ...

protected override void OnInit(EventArgs e){
  placeholder.Controls.Add(Factory.CreateControl());
  base.OnInit(e);
}

This is the only update panel on the page.

The control requires some initial javascript be run for it to work correctly. The control calls:

ScriptManager.RegisterStartupScript(this, GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

and I have also tried:

ScriptManager.RegisterStartupScript(Page, Page.GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

The problem is that the script runs correctly when the page is first displayed, but does not re-run after a partial postback. I have tried the following:

  1. Calling RegisterStartupScript from CreateChildControls
  2. Calling RegisterStartupScript from OnLoad / OnPreRender
  3. Using different combinations of parameters for the first two parameters (in the example above the Control is Page and Type is GetType(), but I have tried using the control itself, etc).
  4. I have tried using persistent and new ids (not that I believe this should have a major impact either way).
  5. I have used a few breakpoints and so have verified that the Register line is being called correctly.

The only thing I have not tried is using the UpdatePanel itself as the Control and Type, as I do not believe the control should be aware of the update panel (and in any case there does not seem to be a good way of getting the update panel?).

Can anyone see what I might be doing wrong in the above?

Thanks :)


Well, to answer the query above - it does appear as if the placeholder somehow messes up the ScriptManager.RegisterStartupScript.

When I pull the control out of the placeholder and code it directly onto the page the Register script works correctly (I am also using the control itself as a parameter).


ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(), script, true);

Can anyone throw any light on why an injected control onto a PlaceHolder would prevent the ScriptManager from correctly registering the script? I am guessing this might have something to do with the lifecycle of dynamic controls, but would appreciate (for my own knowledge) if there is a correct process for the above.

Answer

dc2009 picture dc2009 · Nov 9, 2009

I had an issue using this in a user control (in a page this worked fine); the Button1 is inside an updatepanel, and the scriptmanager is on the usercontrol.

protected void Button1_Click(object sender, EventArgs e)  
{  
    string scriptstring = "alert('Welcome');";  
    ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscript", scriptstring, true);  
}

Now it seems you have to be careful with the first two arguments, they need to reference your page, not your control

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true);