以编程方式将 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 添加到页面?的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式将 UISearchBar 添加到普通 ViewController 中以编程方式添加的 UITableView