Domanda

Sto sviluppando una WebPart (verrà utilizzata in un ambiente SharePoint, sebbene non utilizzi il modello a oggetti) in cui voglio esporre la funzionalità AJAX. A causa della natura dell'ambiente, l'aggiunta di Script Manager direttamente a la pagina non è un'opzione e quindi deve essere aggiunta a livello di codice. Ho tentato di aggiungere il controllo ScriptManager alla pagina nel mio codice webpart.

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); 
    }
}

Tuttavia, quando viene eseguito questo codice, viene visualizzato il seguente messaggio di errore:

  

" La raccolta dei controlli non può essere modificata durante le fasi DataBind, Init, Load, PreRender o Unload. "

Esiste un altro modo per aggiungere ScriptManager alla pagina da una WebPart, o dovrò semplicemente aggiungere ScriptManager a ciascuna pagina (o pagina master) che utilizzerà WebPart?

È stato utile?

Soluzione

Sono stato in grado di farlo funzionare utilizzando l'evento Init di Page:

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);
}

Altri suggerimenti

L'ho fatto e funziona. Crea un segnaposto per i controlli:

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

Quindi puoi farlo in CreateChildControls:

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

Ho riscontrato questo problema con un controllo server ascx personalizzato. Ho provato molte soluzioni che coinvolgono l'aggiunta di script agli eventi OnInit del controllo (che non viene eseguito fino a quando non verifica il controllo ScriptManager), aggiungendo la logica all'interno dei tag del server sul controllo e aggiungendo elementi su ogni altro evento. Non buono. Alla fine ho creato un controllo che eredita da ScriptManagerProxy e quindi utilizza il pezzo di codice di ktrauberman, leggermente modificato, per aggiungere uno ScriptManager se necessario:

  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);
    }
  }

È stato per me.

Ho avuto lo stesso problema di base che il resto di voi ha avuto. Stavo creando un controllo ascx personalizzato e volevo essere in grado di non preoccuparmi se la pagina chiamante fosse stata dichiarata dallo scriptmanager. Ho risolto i problemi aggiungendo quanto segue al contorl ascx stesso.

alla pagina ascx -

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

nel pannello di aggiornamento stesso - oninit="updatePanel1_Init"

al file 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);
     }
}

Grazie a tutti gli altri in questa discussione che mi hanno iniziato.

Questo è l'unico modo in cui ho potuto far funzionare il mio pannello di aggiornamento in una webpart compatibile con sharepoint 2007/2010. Usiamo una pagina master 2010 con uno scriptmanager ma una pagina master 2007 senza 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);
    }
}

Ho usato questo codice nei controlli web personalizzati (.cs) che contengono pannelli di aggiornamento.

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);
    }
    //...
}

Ho avuto questo problema simile e ho scoperto che il modo migliore era quello di aggiungere uno ScriptManager globale alla pagina master, quindi nel codice dietro puoi aggiungerlo tramite:

ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(virtualPath));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top