Добавить ScriptManager на Страницу программно?
-
06-07-2019 - |
Вопрос
Я разрабатываю веб-страницу (она будет использоваться в среде SharePoint, хотя и не использует объектную модель), в которой я хочу предоставить функциональность AJAX.Из-за особенностей среды добавление менеджера сценариев непосредственно на страницу невозможно, поэтому оно должно быть добавлено программным путем.Я попытался добавить элемент управления 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);
}
}
Однако, когда этот код выполняется, я получаю следующее сообщение об ошибке:
"Коллекция элементов управления не может быть изменена на этапах привязки данных, инициализации, загрузки, предварительного просмотра или выгрузки".
Есть ли другой способ добавить ScriptManager на страницу из веб-раздела, или мне придется просто добавлять ScriptManager на каждую страницу (или главную страницу), которая будет использовать веб-раздел?
Решение
Я смог заставить это работать, используя событие инициализации Страницы:
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);
}
Другие советы
Я сделал это, и это работает.Создайте заполнитель для элементов управления:
<asp:PlaceHolder ID="WebGridPlaceholder" runat="server" >
</asp:PlaceHolder>
Затем вы можете сделать это в CreateChildControls:
ScriptManager aSM = new ScriptManager();
aSM.ID = "GridScriptManager";
WebGridPlaceholder.Controls.Add(aSM);
Я столкнулся с этой проблемой с пользовательским элементом управления 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);
}
}
Это сделало это за меня.
У меня была та же основная проблема, что и у всех вас.Я создавал пользовательский элемент управления 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);
}
}
Спасибо всем остальным в этой теме, кто помог мне начать.
Это единственный способ заставить мою панель обновления работать в веб-части, совместимой с sharepoint 2007 / 2010.Мы используем главную страницу 2010 года с scriptmanager, но главную страницу 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);
}
}
Я использовал этот код в пользовательских веб-элементах управления (.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));