简体   繁体   English

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

[英]Add ScriptManager to Page Programmatically?

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. 我正在开发一个WebPart(它将在SharePoint环境中使用,虽然它不使用对象模型)我想要公开AJAX功能。由于环境的性质,直接向页面添加脚本管理器是不是一个选项,因此必须以编程方式添加。 I have attempted to add the ScriptManager control to the page in my webpart code. 我试图将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的每个页面(或母版页)?

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

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

I ran into this problem with a custom ascx server control. 我用自定义的ascx服务器控件遇到了这个问题。 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. 我尝试了许多解决方案,包括向控件的OnInit事件添加脚本(在检查ScriptManager控件之前不会执行),在控件上的服务器标签内添加逻辑,并向其他所有事件添加内容。 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: 我最终构建了一个继承自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. 这样做对我来说。

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. 我正在创建一个自定义的ascx控件,并希望能够不担心调用页面是否声明了scriptmanager。 I got around the issues by adding the following to the ascx contorl itself. 我通过在ascx contorl本身添加以下内容解决了这些问题。

to the ascx page - 到ascx页面 -

<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. 感谢这个让我开始的线程中的其他人。

This is the only way I could get my update panel to work in a sharepoint 2007 / 2010 compatible webpart. 这是我可以让我的更新面板在兼容性的2007/2010兼容webpart中工作的唯一方法。 We use a 2010 master page with an scriptmanager but a 2007 master page without one. 我们使用带有scriptmanager的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);
    }
}

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM