Добавить ScriptManager на страницу программно? - PullRequest
28 голосов
/ 08 октября 2008

Я разрабатываю веб-часть (она будет использоваться в среде SharePoint, хотя она не использует объектную модель), в которой я хочу показать функциональность AJAX. Из-за характера среды добавьте диспетчер скриптов непосредственно страница не является опцией, и поэтому должна быть добавлена ​​программно. Я попытался добавить элемент управления 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); 
    }
}

Однако, когда этот код выполняется, я получаю следующее сообщение об ошибке:

"Невозможно изменить коллекцию элементов управления на этапах DataBind, Init, Load, PreRender или Unload."

Есть ли другой способ добавить ScriptManager на страницу из веб-части или мне нужно будет просто добавить ScriptManager на каждую страницу (или главную страницу), которая будет использовать веб-часть?

Ответы [ 7 ]

41 голосов
/ 08 октября 2008

Мне удалось заставить это работать с помощью события 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);
}
6 голосов
/ 06 декабря 2008

Я сделал это, и это работает. Создайте заполнитель для элементов управления:

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

Затем вы можете сделать это в CreateChildControls:

ScriptManager aSM = new ScriptManager();
aSM.ID = "GridScriptManager";
WebGridPlaceholder.Controls.Add(aSM);
5 голосов
/ 19 ноября 2009

У меня была такая же основная проблема, как и у всех остальных. Я создавал собственный элемент управления 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);
     }
}

Спасибо всем остальным в этой ветке, кто меня начал.

5 голосов
/ 18 сентября 2009

Я столкнулся с этой проблемой с пользовательским элементом управления 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);
    }
  }

Это сделало это для меня.

2 голосов
/ 11 апреля 2011

Это единственный способ заставить мою панель обновлений работать в веб-части, совместимой с sharepoint 2007/2010. Мы используем главную страницу 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 голос
/ 14 февраля 2014

Я использовал этот код в пользовательских веб-элементах управления (.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);
    }
    //...
}
0 голосов
/ 26 марта 2009

У меня была похожая проблема, и я обнаружил, что наилучшим способом было бы добавить глобальный ScriptManager на главную страницу, а затем добавить в него следующий код:

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