Showing posts with label scriptmanager. Show all posts
Showing posts with label scriptmanager. Show all posts

Saturday, March 24, 2012

Is a ScriptManager required in every page?

Hi there,

Is there a way to avoid adding a ScriptManager control to every page, just to set the EnablePartialRendering to true? Maybe the partial rendering setting can be configured in Web.Config or somewhere else.

Thanks,

-BentonAgreed. It would be nice to only have to add the ScriptManager in 1 place
instead of every page. I can also understand the other side which says that
by having the ScriptManager in each page, you only add it where it is
needed. However, having it by default if I create an "Atlas" web project
would be a great thing.

Wally

wrote in message news:1201622@.66.129.67.203...
> Hi there,
>
> Is there a way to avoid adding a ScriptManager control to every page, just
> to set the EnablePartialRendering to true? Maybe the partial rendering
> setting can be configured in Web.Config or somewhere else.
>
> Thanks,
>
> -Benton
>

Its not that simple. ScriptManager does a whole lot more than provide a way to enable partial rendering. It orchestrates the entire process by hooking into the page lifecycle in very interesting ways. It also provides a way to define script and script references (typically these are per page, and the config mechanism for per-page settings via location tags is in my opinion really ugly and non-designable).

Scriptmanager also provides APIs used at runtime to make it possible to generate the desired rendering. See my post:http://www.nikhilk.net/AtlasScriptManager.aspx.

The lifecycle bits and APIs could theoretically be implementated via a base AtlasPage class... but this is much more heavy handed approach than adding a control - surely you don't want to have to rebase all your existing page classes from a new base (esp. hard without multiple inheritance)

Hope that explains the current design. I agree if all it did was provide that property, a config option would be just as fine (though in an ideal world you'd want all that on the <pages> section, and in the Page directive, which cannot be done until System.Web is rev'd)


What about putting it in a Master Page..

A.


I've never been able to use Atlas in Masterpages, so I don't know if that will work at this time.


I have the same problem... Do you think it′s an individual configuration problem or it′s an ATLAS problem itself?
Hi,

could you give some examples of the issues you are having with MasterPages?

Wednesday, March 21, 2012

Is it possible to add a ScriptManager to a page dynamically?

As per the title, is it possible to add a script manager to a page from code?

I have it working OK if the UpdatePanel is also created in code (explicitly after the script manager is created) but not if the UpdatePanel is defined in the aspx template. In that case, if I put my code in "OnInit", the page raises an exception saying that "the Script manager needs to be added (to the page's control tree) before the UpdatePanel", whereas if I move the code to "OnPreInit" then the controls collection is not even created yet.

In other words, adding the Script Manager "OnPreInit" is too early but adding it "OnInit" is too late IF the UpdatePanel is defined in the aspx.

The reason I'm asking is that it would be nice to be able to write controls that could detect if the Page they are hosted in has a Script Manager (or proxy?) and if not, and if they need to use AJAX, then the control can add one, theus removing this dependancy and "knowledge of the implementation" from the client using the control.

Any ideas?

Many thanks

I use a simple workaround-- add a property that says UseAJAX (boolean), and in the XML documentation for the control I say that if the control is on a page with a ScriptManager, or in an UpdatePanel, to set this value to true.

Then the control takes this into account when instantiating and building the control structure, as well as when registering scripts.


OK thanks, that would be OK - obviously this is something you've already come across and worked around.

I did have some ideas on these lines myself, like having an IAjaxControl interface that had a method like "EnableAjax()" that would create & append the UpdatePanels to the control - one of the reasons being that the UpdatePanels, once created and added to the control tree CANNOT be moved so if the client wants to take the control and move it to another part of the tree then it will cause an exception. Having the method, rather than a property, gives the client some control as to WHEN to trigger the creation of the Ajax components (ideally after the control tree is "set in stone").

With hindsight, I think I like your idea of a simple boolean property (but defined in the IAjaxControl interface) and always create the UpdatePanels in the OnLoad (if the boolean is true) rather than beforehand - hopefully then the control tree is final and we are safe to do it, and the GUI designer can support the boolean property withought the need for coding from the client.

I felt the interface was needed for scenarios like where a different control CONTAINED your Ajax enabled control - it too would then need to support the property (and pass it down to your control it was containing).


Did you find a solution (Like you, I try the OnInit and the PreOnInit) ?

All my pages inherits the same class (let's say PageAncestry). I want to add the scriptmanager with code in PageAncestry so all my pages will automatically be able to use ajax.


After some google search, I finally found a solution on this page http://www.capdes.com/2007/02/microsoft_office_sharepoint_se.html

Add the ScriptManager in the PreInit at the HtmlForm first position :

Private Sub Page_PreInit(ByVal poSender As Object, ByVal poArguments As System.EventArgs) Handles Me.PreInit

' Get current ScriptManager if exist
Dim oScriptManagerAjax As ScriptManager = ScriptManager.GetCurrent(Me)
' If not exist
If oScriptManagerAjax Is Nothing Then
' Create one
oScriptManagerAjax = New ScriptManager
' Get page form
Dim oForm As HtmlForm = Me.Form
' If form present
If Not IsNothing(oForm) Then
' Add it at first position
oForm.Controls.AddAt(0, oScriptManagerAjax)
Else
' Manage if not (impossible to use Ajax)
End If
End If


End Sub


Hmm, from what I was saying:

"whereas if I move the code to "OnPreInit" then the controls collection is not even created yet."

and yet, in "PreInit" you have code:

oForm.Controls.AddAt(0, oScriptManagerAjax)

Are you sure thius works? According to my original post "oForm.Controls.Add" should have raised an exception as the "Controls" collection is not yet created. Are you sure your code works?

My page also uses a MasterPage - does yours? Does that make a difference (i wonder??)

I'll give it a try tomorrow. Thanks for the post :)


Yes it's working for me.

I don't have a master page, so I don't know if it's working with.

The most important thing is theControls.addat(0, it put the ScriptManager before all other controls define in the form (even the one in design). It's not working if you use only Controls.add


I'm pretty sure that "Controls.AddAt(0..." is what I was using before - as I said though, I believe the "Controls" collection was null at PreInit.

Anyway, I will try again and post my results :)


No mate, this just doesn't work, not in C# anyway.

The isssue is as before but I was mistaken, it's not the Control collection that is not created, it is the Form object itself.

Here is my ASPX Template:

<%@. Page Language="C#" AutoEventWireup="true" CodeFile="Page2.aspx.cs" Inherits="Page2" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <div> Page 2<br /> <br /> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br /> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> </ContentTemplate> </asp:UpdatePanel> </div> </form></body></html>

And here is my code behind:

using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;public partialclass Page2 : Page{protected override void OnPreInit(EventArgs e) {// Pop a script manager on the page if one does not yet exist. ScriptManager scriptManager = ScriptManager.GetCurrent(this);if (scriptManager ==null) { scriptManager =new ScriptManager(); HtmlForm form =this.Form;if (form !=null) form.Controls.AddAt(0, scriptManager); }base.OnPreInit(e); }protected void Button1_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToLongTimeString(); }}

As you see here, if "form" is null we can't add the script manager, and this.Form IS null at "PreInit":

if

(form !=null)
form.Controls.AddAt(0, scriptManager);

The only way I could get this to work is doing it in the "Onint" where the ScriptManager is created first and then the UpdatePanel created IN CODE afterwards (NOT defined in the aspx). Unfortunately, defining the Update Panel in the aspx means that "Oninit" is too late to add the script manager, but "PreInit" is too early as the form is not yet created.

Please tell me I'm wrong about this - how have you got this to work? I don't get it. Can you post your ASPX & VB code?



Not works!!!

Obviously the code is in the OnInit andnot in OnPreInit at http://www.capdes.com/2007/02/microsoft_office_sharepoint_se.htmlSmile

I think the msdn documentation not correct about the preinit event, this is an excerpt of my offline msdn library (seeit online):

PreInit

Use this event for the following:

Check theIsPostBack property to determine whether this is the first time the page is being processed.


Yes stmarti, although I think the documentation is (technically) correct in that you can CREATE controls at OnPreInit but you CANNOT add them to your Form, as it does not yet exist!

If you do this in OnPreInit:

Label label =newLabel();
label.Text ="Hello PreInit world";
this.Controls.Add(label);

and you'll see that the label ends up rendering AFTER ALL HTML MARKUP!!!! (ie was added to the control tree FIRST, then the Form was Added AT(0) with all real content then added to the form - leaving your poor Label "out in the cold".

So if the Form is not yet created at OnPreInit, I can't see how the VB code posted above could work.


Just tested this:

Private Sub Page_PreInit(ByVal poSender As Object, ByVal poArguments As System.EventArgs) Handles Me.PreInit

' Get current ScriptManager if exist
Dim oScriptManagerAjax As ScriptManager = ScriptManager.GetCurrent(Me)
' If not exist
If oScriptManagerAjax Is Nothing Then
' Create one
oScriptManagerAjax = New ScriptManager
' Get page form
Dim oForm As HtmlForm = Me.Form
' If form present
If Not IsNothing(oForm) Then
' Add it at first position
oForm.Controls.AddAt(0, oScriptManagerAjax)
Else
' Manage if not (impossible to use Ajax)
End If
End If

End Sub

And it works.... only when you havealreadya scriptmanager in the aspx. Obviously this code in real do nothing special because:

- if you have already a scriptmanager on the page the code does nothing, and your page is just fine...

- if you have not a scriptmanager in the aspx, the following code

' Add it at first position
oForm.Controls.AddAt(0, oScriptManagerAjax)

neverwill be executed because oForm is null in preinitSmile! Anyway your page will throw exception and cry for a scriptmanager...


VR2:

Yes stmarti, although I think the documentation is (technically) correct in that you can CREATE controls at OnPreInit but you CANNOT add them to your Form, as it does not yet exist!

You are right. Technically it's correct. The doc (at least this entry in msdn) suggest preinit for creating dynamic controls, and init for setting control properties. This is not true for the form's controls, would be nice a remark about it in the future.


I try your C# code and it's not working :(

But I found the difference with my vb code :) (I can't post it, it's included in a bigger class)

I use FindControl to search the Form !

Just change the OnPreInit in your code by this one and it's workingBig Smile
protected override void OnPreInit(EventArgs e) { ScriptManager scriptManager = ScriptManager.GetCurrent(this);if (scriptManager ==null) { scriptManager =new ScriptManager(); Control oControl =this.FindControl("Form1");if (oControl !=null) { oControl.Controls.AddAt(0, scriptManager); } }base.OnPreInit(e); }

It works!!! Like thisBig Smile:

protected override void OnPreInit( EventArgs e )
{
HtmlForm form1 = ( HtmlForm )this.FindControl( "Form1" );

ScriptManager temp = new ScriptManager( );
temp.EnablePageMethods = true;

form1.Controls.AddAt( 0, temp );

base.OnPreInit( e );
}

Great work gbarry! The problem solved and the answere for:

Is it possible to add a ScriptManager to a page dynamically?

is:yes! Yes

Is it possible to add a ScriptManager and/or UpdatePanel to a MasterPage from a ContentPag

I would on like AJAX on one content page and want to add an UpdatePanel to the MasterPage and wrap a UserControl that is being loaded from the MasterPage in that UpdatePanel all from the ContentPage. Is it possbile to do this? I have some code but it is not working.

protected override void OnPreInit( EventArgs e ) { ScriptManager sm =new ScriptManager(); sm.ID ="ScriptManager1"; Master.Controls.Add( sm ); UpdatePanel panel =new UpdatePanel(); panel.ID ="upMaster"; panel.ContentTemplateContainer.Controls.Add(this.Controls[0] ); AsyncPostBackTrigger trig =new AsyncPostBackTrigger(); trig.ControlID ="btnDelete"; trig.EventName ="Click"; panel.Triggers.Add( trig ); Master.Controls.Add( panel );base.OnPreInit( e ); }

I changed my code and now can get the page to load but now I dont see my usercontrol on the masterpage

protected override void OnPreInit( EventArgs e ) { UpdatePanel panel =new UpdatePanel(); panel.ID ="upMaster"; UserControl uc = (( UserControl )Master.FindControl("CartSummary1" )); panel.ContentTemplateContainer.Controls.Add( uc ); panel. //AsyncPostBackTrigger trig =new AsyncPostBackTrigger();//trig.ControlID = "btnDelete"; //trig.EventName = "Click"; //panel.Triggers.Add( trig ); HtmlForm form1 = ( HtmlForm )Master.FindControl("Form1" ); form1.Controls.Add( panel );//Master.Controls.Add( panel );base.OnPreInit( e ); }

Yes,It is possible.

Do it like this:

MasterPage.master:

<%@. Master Language="C#" %>
<%@. Register src="http://pics.10026.com/?src=UserControlA.ascx" TagName="UserControlA" TagPrefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

</script>


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:UserControlA ID="uc1" runat="server" />
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
<asp:contentplaceholder id="ContentPlaceHolder2" runat="server">
</asp:contentplaceholder>
</div>
</form>
</body>
</html>

Default.aspx:

<%@. Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Untitled Page" %>

<script runat="server">

protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text = DateTime.Now.ToString();
}


protected void Page_PreInit(object sender, EventArgs e)
{
HtmlForm form1 = (HtmlForm)Master.FindControl("form1");
ScriptManager sm = new ScriptManager();
sm.ID = "ScriptManager1";
form1.Controls.AddAt(0, sm);

UpdatePanel panel = new UpdatePanel();
panel.ID = "upMaster";
UserControl uc = ((UserControl)Master.FindControl("uc1"));
panel.ContentTemplateContainer.Controls.Add(uc);
form1.Controls.Add(panel);
}

</script>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<div style="display:none;"><asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button1_Click" /></div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">
<script type="text/javascript" language="javascript">
function doclick(){
$get('<%= Button2.ClientID%>').click();
}
</script>
<asp:Button ID="Button1" runat="server" Text="Button" UseSubmitBehavior="false" OnClientClick="doclick();return false;" />
</asp:Content>

UserControlA.ascx:

<%@. Control Language="C#" ClassName="UserControlA" %>

<asp:TextBox ID="TextBox1" runat="server">TextBox in UserControlA</asp:TextBox>

Best Regards,