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

Posted

技术标签:

【中文标题】以编程方式将 ScriptManager 添加到页面?【英文标题】:Add ScriptManager to Page Programmatically? 【发布时间】:2010-09-16 02:02:33 【问题描述】:

我正在开发一个我想在其中公开 AJAX 功能的 WebPart(它将在 SharePoint 环境中使用,尽管它不使用对象模型)。由于环境的性质,将脚本管理器直接添加到该页面不是一个选项,因此必须以编程方式添加。我已尝试将 ScriptManager 控件添加到我的 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); 
    

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

“在 DataBind、Init、Load、PreRender 或 Unload 阶段不能修改控件集合。”

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

【问题讨论】:

【参考方案1】:

我可以通过使用页面的 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);

【讨论】:

不,如果您注意到,我正在检查以确保在添加之前页面上没有 ScriptManager。 这个OnInit是控件的方法吗? 是的。我在 WebPart 中使用它,但这只是一个控件。 不适用于更新面板...通过Page.Items[typeof(ScriptManager)] = newScriptManager设置脚本管理器的正确方法。 我的一个用户控件中有这个方法,但它仍然抱怨说:“ID 为“upd”的控件需要页面上的 ScriptManager。 ScriptManager 必须出现在任何需要它的控件之前。'【参考方案2】:

我遇到了和你们一样的基本问题。我正在创建一个自定义 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);
     

感谢本主题中帮助我入门的其他所有人。

【讨论】:

DateTime.Now.Ticks 附加到 ScriptManager 的 ID 的任何原因? 我刚刚在用户控件中使用了这个解决方案,它是我发现的唯一一个有效的解决方案!谢谢!我确实必须将 sManager.ID = "sManager_" + DateTime.Now.Ticks; 更改为 sManager.ID = "ScriptManager1"; 以避免在我的 UpdatePanel 中出现奇怪的行为。【参考方案3】:

我已经这样做了,它有效。为控件创建一个占位符:

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

然后你可以在 CreateChildControls 中做到这一点:

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

【讨论】:

【参考方案4】:

我在使用自定义 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);
    
  

这对我有用。

【讨论】:

【参考方案5】:

这是让我的更新面板在与 sharepoint 2007 / 2010 兼容的 webpart 中工作的唯一方法。我们使用带有脚本管理器的 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);
    

【讨论】:

【参考方案6】:

我在包含更新面板的自定义 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);
    
    //...

【讨论】:

【参考方案7】:

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

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

【讨论】:

以上是关于以编程方式将 ScriptManager 添加到页面?的主要内容,如果未能解决你的问题,请参考以下文章

将图标添加到页脚

php 将页面内容添加到页脚版权

只能将一个ScriptManager实例添加到页面错误中

以编程方式将 UISearchBar 添加到普通 ViewController 中以编程方式添加的 UITableView

以编程方式将按钮添加到导航栏

如何以编程方式将空间添加到任务控制?