2008-10-08 10 views
28

Ich entwickle ein WebPart (es wird in einer SharePoint-Umgebung verwendet werden, obwohl es nicht das Objektmodell verwendet), die ich AJAX-Funktionalität in. Offenbar aufgrund der Art der Umgebung, Hinzufügen des Skript-Manager direkt zu der Seite ist keine Option und muss daher programmgesteuert hinzugefügt werden. Ich habe versucht, das ScriptManager-Steuerelement der Seite in meinem Webpart-Code hinzuzufügen.SkriptManager zu Seite programmgesteuert hinzufügen?

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

Wenn jedoch dieser Code ausgeführt wird, erhalte ich die folgende Fehlermeldung:

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

Gibt es einen anderen Weg, um die Script auf die Seite von einem WebPart hinzuzufügen, oder werde ich um den ScriptManager zu jeder Seite (oder Masterseite) hinzuzufügen, die das WebPart verwenden wird?

Antwort

40

Ich konnte dies durch die Verwendung der Seite der Init-Ereignisses zur Arbeit kommen:

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

Ich frage mich, ob dies mit mehr als eine Script auf der Seite führen kann ... – vitule

+3

Nein, Wenn Sie bemerken, bin Überprüfung ich, um sicherzustellen, dass es kein Script auf der Seite eines vor der Zugabe. –

+0

Ist das OnInit eine Methode der Kontrolle? – Shuo

6

Ich habe dies getan, und es funktioniert. Erstellen Sie einen Platzhalter für die Kontrollen:

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

Dann können Sie dies in Createchild:

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

Ich hatte dieses ähnliches Problem und fand der beste Weg, ein globales Script zum Masterpage dann hinzuzufügen war in Der Code hinter Ihnen kann hinzugefügt werden durch:

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

Ich lief in dieses Problem mit einem benutzerdefinierten Ascx-Server-Steuerelement. Ich habe viele Lösungen ausprobiert, die das Hinzufügen von Skript zu den OnInit-Ereignissen des Steuerelements beinhalten (das nicht ausgeführt wird, bis es nach dem ScriptManager-Steuerelement sucht), Hinzufügen von Logik innerhalb von Server-Tags auf dem Steuerelement und Hinzufügen von Dingen zu jedem anderen Ereignis. Nicht gut. Ich baute schließlich ein Steuerelement, das von Script erbt und verwendet dann ktrauberman des Stück Code, leicht modifiziert, ein Script hinzufügen, wenn erforderlich:

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

, dass es für mich getan hat.

4

Ich hatte das gleiche grundlegende Problem, das der Rest von Ihnen hatte. Ich habe ein benutzerdefiniertes ascx-Steuerelement erstellt und wollte mir keine Sorgen darüber machen, ob auf der aufrufenden Seite der scriptmanager deklariert wurde oder nicht. Ich habe die Probleme gelöst, indem ich folgendes zum ascx contorl selbst hinzugefügt habe.

zur ascx Seite -

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

in dem Update-Panel selbst - oninit="updatePanel1_Init"

zur ascx.cs Datei -

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

Vielen Dank an alle anderen in diesem Thread, die gekommen sind ich fing an.

2

Dies ist der einzige Weg, wie ich mein Update-Panel in einem Sharepoint 2007/2010-kompatiblen Webpart verwenden kann. Wir verwenden eine Masterseite 2010 mit einem Scriptmanager, aber eine Masterseite 2007 ohne eine.

.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

benutzte ich diesen Code in benutzerdefinierten Web-Kontrollen (CS-), die Update-Panels enthalten.

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); 
    } 
    //... 
}