【问题标题】:Add ScriptManager to Page Programmatically?以编程方式将 ScriptManager 添加到页面?
【发布时间】: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 的每个页面(或母版页)?

【问题讨论】:

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


    【解决方案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));
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多