以编程方式将ScriptManager添加到页面?

时间:2008-10-08 17:43:00

标签: c# sharepoint-2007 web-parts scriptmanager

我正在开发一个WebPart(它将在SharePoint环境中使用,虽然它不使用对象模型)我想要公开AJAX功能。由于环境的性质,直接添加脚本管理器该页面不是一个选项,因此必须以编程方式添加。我试图在我的webpart代码中将ScriptManager控件添加到页面中。

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

但是,执行此代码时,我收到以下错误消息:

  

“在DataBind,Init,Load,PreRender或Unload阶段无法修改控件集合。”

是否有另一种方法将ScriptManager从WebPart添加到页面中,或者我是否只需将ScriptManager添加到将使用WebPart的每个页面(或母版页)?

7 个答案:

答案 0 :(得分:41)

我能够通过使用Page的Init事件来实现这一点:

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

答案 1 :(得分:6)

我已经完成了这项工作。为控件创建占位符:

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

然后你可以在CreateChildControls中执行此操作:

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

答案 2 :(得分:5)

我使用自定义ascx服务器控件遇到了这个问题。我尝试了许多解决方案,包括向控件的OnInit事件添加脚本(在检查ScriptManager控件之前不会执行),在控件上的服务器标签内添加逻辑,并向其他所有事件添加内容。不好。我最终构建了一个继承自ScriptManagerProxy的控件,然后使用ktrauberman的一段代码(稍加修改)在需要时添加ScriptManager:

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

这是为我做的。

答案 3 :(得分:5)

我和你们其他人有同样的基本问题。我正在创建一个自定义的ascx控件,并希望能够不担心调用页面是否声明了scriptmanager。我通过在ascx contorl本身添加以下内容解决了这些问题。

到ascx页面

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

更新面板中的

- oninit="updatePanel1_Init"

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

感谢此主题中的其他人让我开始。

答案 4 :(得分:2)

这是我可以让我的更新面板在兼容2007/2010兼容的webpart中工作的唯一方法。我们使用带有scriptmanager的2010主页,但是没有一个的2007主页。

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

答案 5 :(得分:1)

我在包含更新面板的自定义Web控件(.cs)中使用了此代码。

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

答案 6 :(得分:0)

我遇到了类似的问题,并发现最好的方法是将全局ScriptManager添加到母版页,然后在后面的代码中添加它:

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