Pergunta

Estou desenvolvendo um WebPart (ele será usado em um ambiente SharePoint, apesar de não usar o Object Model) que eu quero expor a funcionalidade AJAX dentro. Por causa da natureza do ambiente, acrescentando que o Script Manager diretamente para a página não é uma opção, e assim deve ser adicionado por meio de programação. Tentei adicionar o controle ScriptManager para a página no meu código 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); 
    }
}

No entanto, quando esse código é executado, recebo a seguinte mensagem de erro:

"A coleção de controle não pode ser modificado durante as fases DataBind, Init, Load, PreRender ou descarregar."

Existe outra maneira para adicionar o ScriptManager para a página a partir de um WebPart, ou eu vou ter que basta adicionar o ScriptManager para cada página (ou página principal) que irá utilizar o WebPart?

Foi útil?

Solução

Eu era capaz de chegar a este trabalho usando evento Init da 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);
}

Outras dicas

Eu fiz isso e ele funciona. Criar um espaço reservado para os controles:

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

Em seguida, você pode fazer isso em CreateChildControls:

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

Eu corri para este problema com um controle de servidor ascx personalizado. Eu tentei muitas soluções que envolvem a adição de script para os eventos OnInit do controle (que não são executadas até depois ele verifica o controle ScriptManager), a adição do interior lógica de tags do servidor no controle, e acrescentando coisas para todos os outros eventos. Nada de bom. Eu finalmente construiu um controle que herda de ScriptManagerProxy e, em seguida, usa parte do código do ktrauberman, ligeiramente modificada, para adicionar um ScriptManager se necessário:

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

Isso fez isso por mim.

Eu tive o mesmo problema básico o resto do que você tinha. Eu estava criando um controle ascx personalizado e queria ser capaz de não se preocupar ou não a página chamando teve a scriptmanager declarou. Eu tenho em torno das questões, adicionando a seguinte para o próprio contorl ascx.

à página ascx -

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

em si mesmo painel de atualização - oninit="updatePanel1_Init"

para o arquivo 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);
     }
}

Obrigado a todos os outros nesta discussão que me iniciou.

Esta é a única maneira que eu poderia obter o meu painel de atualização para o trabalho em um sharepoint 2007/2010 webpart compatível. Nós usamos uma página 2010 principal com um scriptmanager mas uma página de 2007 mestre sem um.

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

Eu usei esse código em controles personalizados de Web (cs) que contêm painéis de atualização.

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

Eu tive esse problema semelhante e encontrou a melhor maneira era para adicionar um ScriptManager global para o masterpage em seguida, no código por trás você pode adicionar a ele por:

ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(virtualPath));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top