Вопрос

Я разрабатываю веб-страницу (она будет использоваться в среде 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));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top