2008-10-08 19 views
28

Estoy desarrollando un WebPart (se usará en un entorno de SharePoint, aunque no usa el Modelo de objetos) en el que quiero exponer la funcionalidad AJAX. Debido a la naturaleza del entorno, Agregar el Administrador de scripts directamente al la página no es una opción, por lo que debe agregarse mediante programación. Intenté agregar el control ScriptManager a la página en mi código de webpart.¿Agregar ScriptManager a la página mediante programación?

protected override void CreateChildControls() 
{ 
    if (ScriptManager.GetCurrent(Page) == null) 
    { 
     ScriptManager sMgr = new ScriptManager(); 
     // Ensure the ScriptManager is the first control. 
     Page.Form.Controls.AddAt(0, sMgr); 
    } 
} 

Sin embargo, cuando se ejecuta este código, me sale el siguiente mensaje de error:

"The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."

¿Hay otra manera de añadir el ScriptManager a la página de un WebPart, o voy a tener simplemente agregar el ScriptManager a cada página (o página maestra) que usará el WebPart?

Respuesta

40

que era capaz de conseguir que esto funcione mediante el uso de evento Init de la página:

protected override void OnInit(EventArgs e) 
{ 
    Page.Init += delegate(object sender, EventArgs e_Init) 
       { 
        if (ScriptManager.GetCurrent(Page) == null) 
        { 
         ScriptManager sMgr = new ScriptManager(); 
         Page.Form.Controls.AddAt(0, sMgr); 
        } 
       }; 
    base.OnInit(e); 
} 
+0

Me pregunto si esto puede llevar a tener más de un ScriptManager en la página ... – vitule

+3

No, si te fijas, estoy comprobando para asegurarse de que no hay ScriptManager en la página antes de agregar uno. –

+0

¿Es esto OnInit un método del control? – Shuo

6

lo he hecho y funciona. Crear un marcador de posición para los controles:

<asp:PlaceHolder ID="WebGridPlaceholder" runat="server" > 
</asp:PlaceHolder> 

entonces usted puede hacer esto en CreateChildControls:

ScriptManager aSM = new ScriptManager(); 
aSM.ID = "GridScriptManager"; 
WebGridPlaceholder.Controls.Add(aSM); 
0

tuve este problema similar y encontrado la mejor manera era añadir un ScriptManager global a la masterpage continuación, en el código detrás de usted puede agregarlo por:

ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(virtualPath)); 
5

Me encontré con este problema con un control de servidor ascx personalizado. Intenté muchas soluciones que implicaban agregar script a los eventos OnInit del control (que no se ejecuta hasta después de que comprueba el control de ScriptManager), agregar lógica dentro de las etiquetas del servidor en el control y agregar cosas a cada otro evento. No es bueno. Finalmente he construido un control que hereda de ScriptManagerProxy y luego utiliza pieza de código, ligeramente modificada de ktrauberman, añadir un ScriptManager si es necesario:

public class ProxiedScriptManager : ScriptManagerProxy 
    { 
    protected override void OnInit(EventArgs e) 
    { 
     //double check for script-manager, if one doesn't exist, 
     //then create one and add it to the page 
     if (ScriptManager.GetCurrent(this.Page) == null) 
     { 
     ScriptManager sManager = new ScriptManager(); 
     sManager.ID = "sManager_" + DateTime.Now.Ticks; 
     Controls.AddAt(0, sManager); 
     } 

     base.OnInit(e); 
    } 
    } 

Eso lo hizo por mí.

4

Tuve el mismo problema básico que el resto de ustedes. Estaba creando un control ascx personalizado y quería poder no preocuparme si la página de llamada tenía o no el scriptmanager declarado. Solucioné los problemas añadiendo lo siguiente al contorl de ascx.

a la página ascx -

<asp:PlaceHolder runat="server" ID="phScriptManager"></asp:PlaceHolder>

en el propio panel de actualización - oninit="updatePanel1_Init"

al archivo ascx.cs -

protected void updatePanel1_Init(object sender, EventArgs e) 
{ 
    if (ScriptManager.GetCurrent(this.Page) == null) 
    { 
     ScriptManager sManager = new ScriptManager(); 
     sManager.ID = "sManager_" + DateTime.Now.Ticks; 
     phScriptManager.Controls.AddAt(0, sManager); 
    } 
} 

Gracias a todos los demás en este hilo que consiguieron yo comencé.

2

Esta es la única forma en que podría hacer funcionar mi panel de actualización en una parte web compatible con Sharepoint 2007/2010. Usamos una página maestra de 2010 con un administrador de scripts pero una página maestra de 2007 sin una.

.ascx

<asp:PlaceHolder ID="sMgr_place" runat="server" /> 
<asp:UpdatePanel runat="server" OnInit="updatePanel_Init"><ContentTemplate> 
... 
</ContentTemplate></asp:UpdatePanel> 

.ascx.cs

public void updatePanel_Init(object sender, EventArgs e) 
{ 
    if (ScriptManager.GetCurrent(Page) == null) 
    { 
     ScriptManager sMgr = new ScriptManager(); 
     sMgr.EnablePartialRendering = true; 
     sMgr_place.Controls.Add(sMgr); 
    } 
} 
1

que utilizan este código en controles web personalizados (cs) que contienen paneles de actualización.

protected override void OnInit(EventArgs e) 
{ 
    //... 
    if (ScriptManager.GetCurrent(this.Page) == null) 
    { 
     ScriptManager scriptManager = new ScriptManager(); 
     scriptManager.ID = "scriptManager_" + DateTime.Now.Ticks; 
     Controls.AddAt(0, scriptManager); 
    } 
    //... 
} 
Cuestiones relacionadas