Getting a scriptmanager into a dynamically rendered page

We are rendering usercontrols dynamically like this:

public string RenderControl(string pathcontrol)
{
    string html;

    var page = new Page();
    var control = page.LoadControl(path);            
    page.Controls.Add(control);

    // do stuff to the control (give it some data to work on)

    using (var writer = new StringWriter())
    {
        HttpContext.Current.Server.Execute(page, writer, false);
        html = writer.ToString();
    }

    return html;
}

This lets us the same user controls when rendering pages normally as we do when rendering responses to ajax calls. However, when adding controls which themselves contain a scriptmanagerProxy we run into the problem that the newed up Page object doesn't contain either a ScriptManager or the HtmlForm in which the ScriptManager needs to run.

Is there any way around this?

Yours Andreas

Answers


As others have said you can add a ScriptManger dynamically easily enough [ Add ScriptManager to Page Programmatically? if your Page object is complete.

Can you try using BuildManager.CreateInstanceFromVirtualPath() to create the Page object instead? You issue may be how you create that object. There's a bit more to creating a new page than newing up the Page object.

Eg.

Page page 
       = BuildManager.CreateInstanceFromVirtualPath("~/Test.aspx", typeof(Page))

See also http://www.west-wind.com/weblog/posts/120530.aspx for a little more background.


Can you do something like this:

page.Form.Controls.AddAt(0, New ScriptManager())

Edit: I think you'd also need to add your control to the page's form, not just to the page itself, right? It's my understanding that the form is created with the page, but if not you should be able to just do:

page.Form = new HtmlForm()

You may also need to do something like:

page.Controls.Add(page.Form)

Sure, the trick is to add it in a page's Init event handler. You can use:

Page.Init += delegate {

  // check for script manager
  if( ScriptManager.GetCurrent(Page) == null ) {

    ScriptManager m = new ScriptManager();
    m.ScriptMode = ScriptMode.Release;
    Page.Form.Controls.AddAt(0, m);

  }

}

I'd recommend avoiding dynamically adding forms to your page if you can. For example, the above code snippet assumes a form is already present on the page.

Update

Sure, thanks for pointing that out Andreas. Here's an update. So, there is no setter for Page.Form - but you are correct in that you can add a new HtmlForm to the Controls collection. Once added, the Page.Form property is no longer null. That will allow you to add the ScriptManager dynamically as seen above. Here is a code sample that shows this working (ASPX file is a simple page without a server side form):

public partial class Pages_Test_DynamicFormSample : Page {

    protected void Page_Init(object sender, EventArgs e) {

        Controls.Add( new HtmlForm() );

        ScriptManager m = new ScriptManager();
        m.ScriptMode = ScriptMode.Release;
        Form.Controls.AddAt(0, m);

    }

    protected void Page_Load(object sender, EventArgs e) {

        // ScriptManager test
        var t1 = new System.Web.UI.WebControls.TextBox();
        var t2 = new System.Web.UI.WebControls.TextBox();
        Form.Controls.Add( t1 );
        Form.Controls.Add( t2 );

        ScriptManager.GetCurrent(Page).SetFocus( t2 );

    }

}

Enjoy - btw, setting the ScriptManager's ScriptMode to Release obviously isn't required. We do it just to avoid some JavaScript bugs found in the Debug version of the ASP.NET script runtime.


Need Your Help

Running Jetty 7 as service on Debian/Ubuntu…

ubuntu service jetty debian

I'm having trouble running jetty 7 as a service in Ubuntu.

Prestashop - Product admin : autocomplete is not called

php jquery autocomplete prestashop

I added a custom field named product_type in Product admin. It works well, but now, I'm trying to add an autocomplete to this field.