2008-10-08 90 views
28

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

然而,执行该代码时,我得到了以下错误消息:

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

有另一种方式来使用ScriptManager从Web部件添加到页面,还是我将不得不只需将ScriptManager添加到将使用WebPart的每个页面(或母版页)?

回答

40

我能得到这个通过页面的初始化事件的工作:

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

我不知道这是否会导致其在页面上不止一个的ScriptManager ...... – vitule 2009-07-21 13:04:25

6

我做这个和它的作品。为控件创建占位符:

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

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

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

我有这个类似的问题,找到了最好的办法是一个全球性的ScriptManager添加到母版,然后在您可以添加到它后面的代码:

ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference(virtualPath)); 
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); 
    } 
    } 

这为我做。

4

我的基本问题和你们其他人一样。我创建了一个自定义的ascx控件,并且希望能够不用担心调用页面是否已经声明了脚本管理器。通过将以下内容添加到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); 
    } 
} 

谢谢谁在这个线程中的其他人我开始了。

2

这是我可以让我的更新面板在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); 
    } 
} 
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); 
    } 
    //... 
} 
相关问题