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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/183950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:00:38  来源:igfitidea点击:

Add ScriptManager to Page Programmatically?

c#sharepoint-2007web-partsscriptmanager

提问by Kyle Trauberman

I am developing a WebPart (it will be used in a SharePoint environment, although it does not use the Object Model) that I want to expose AJAX functionality in. Because of the nature of the environment, Adding the Script Manager directly to the page is not an option, and so must be added programmatically. I have attempted to add the ScriptManager control to the page in my webpart code.

我正在开发一个我想在其中公开 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); 
    }
}

However, when this code is executed, I get the following error message:

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

"The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."

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

Is there another way to add the ScriptManager to the page from a WebPart, or am I going to have to just add the ScriptManager to each page (or master page) that will use the WebPart?

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

采纳答案by Kyle Trauberman

I was able to get this to work by using the Page's Init event:

我能够通过使用 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);
}

回答by daduffer

I've done this and it works. Create a placeholder for the controls:

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

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

Then you can do this in CreateChildControls:

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

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

回答by dkarzon

I had this similar problem and found the best way was to add a global ScriptManager to the masterpage then in the code behind you can add to it by:

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

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

回答by Josh

I ran into this problem with a custom ascx server control. I tried many solutions involving adding script to the OnInit events of the control (which doesn't get executed until after it checks for the ScriptManager control), adding logic inside of server tags on the control, and adding things to about every other event. No good. I finally built a control that inherits from ScriptManagerProxy and then uses ktrauberman's piece of code, slightly modified, to add a ScriptManager if needed:

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

That did it for me.

那是为我做的。

回答by Jon

I had the same basic issue the rest of you had. I was creating a custom ascx control and wanted to be able to not worry about whether or not the calling page had the scriptmanager declared. I got around the issues by adding the following to the ascx contorl itself.

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

to the ascx page -

到 ascx 页面 -

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

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

in the update panel itself - oninit="updatePanel1_Init"

在更新面板本身 - oninit="updatePanel1_Init"

to the ascx.cs 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);
     }
}

Thank you to everyone else in this thread who got me started.

感谢这个线程中让我开始的其他人。

回答by Paul

This is the only way I could get my update panel to work in a sharepoint 2007 / 2010 compatible webpart. We use a 2010 master page with an scriptmanager but a 2007 master page without one.

这是让我的更新面板在与 sharepoint 2007 / 2010 兼容的 webpart 中工作的唯一方法。我们使用带有脚本管理器的 2010 母版页,但使用没有脚本管理器的 2007 母版页。

.ascx

.ascx

<asp:PlaceHolder ID="sMgr_place" runat="server" />
<asp:UpdatePanel runat="server" OnInit="updatePanel_Init"><ContentTemplate>
...
</ContentTemplate></asp:UpdatePanel>

.ascx.cs

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

回答by user3311381

I used this code in custom web controls (.cs) that contain update panels.

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