2008-10-08 42 views
28

Tôi đang phát triển một WebPart (nó sẽ được sử dụng trong môi trường SharePoint, mặc dù nó không sử dụng Mô hình Đối tượng) mà tôi muốn trưng ra chức năng AJAX. Bởi vì bản chất của môi trường, Thêm Trình quản lý Script trực tiếp vào trang không phải là một tùy chọn và do đó phải được thêm theo chương trình. Tôi đã cố thêm điều khiển ScriptManager vào trang trong mã webpart của tôi.Thêm ScriptManager vào Trang theo lập trình?

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

Tuy nhiên, khi mã này được thực thi, tôi nhận được thông báo lỗi sau:

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

Có một cách khác để thêm ScriptManager trang từ một WebPart, hay tôi sẽ phải chỉ cần thêm ScriptManager vào mỗi trang (hoặc trang chính) sẽ sử dụng WebPart?

Trả lời

40

tôi đã có thể có được điều này để làm việc bằng cách sử dụng sự kiện Init của Trang:

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

Tôi tự hỏi nếu điều này có thể dẫn đến việc có nhiều hơn một ScriptManager trên trang ... – vitule

+3

Không, Nếu bạn để ý, tôi đang kiểm tra để đảm bảo rằng không có ScriptManager trên trang trước khi thêm một. –

+0

Đây có phải là OnInit một phương pháp kiểm soát không? – Shuo

6

Tôi đã làm điều này và nó hoạt động. Tạo một giữ chỗ cho điều khiển:

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

Sau đó, bạn có thể làm điều này trong CreateChildControls:

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

Tôi có vấn đề tương tự này và thấy cách tốt nhất là để thêm một ScriptManager toàn cầu để masterpage sau đó trong mã phía sau bạn có thể thêm vào nó bằng cách:

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

Tôi gặp sự cố này với điều khiển máy chủ ascx tùy chỉnh. Tôi đã thử nhiều giải pháp liên quan đến việc thêm tập lệnh vào các sự kiện OnInit của điều khiển (không được thực hiện cho đến khi nó kiểm tra điều khiển ScriptManager), thêm logic bên trong thẻ máy chủ trên điều khiển và thêm mọi thứ vào mọi sự kiện khác. Không tốt. Cuối cùng tôi xây dựng một điều khiển được thừa kế từ ScriptManagerProxy và sau đó sử dụng mảnh ktrauberman của mã, một chút thay đổi, để thêm một ScriptManager nếu cần thiết:

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

Điều đó đã làm nó cho tôi.

4

Tôi có cùng một vấn đề cơ bản với phần còn lại của bạn. Tôi đã tạo ra một điều khiển ascx tùy chỉnh và muốn có thể không phải lo lắng về việc có hay không trang gọi đã có scriptmanager được khai báo. Tôi đã nhận được xung quanh các vấn đề bằng cách thêm sau đây vào contcl ascx chính nó.

vào trang ascx -

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

trong bảng điều khiển cập nhật bản thân - oninit="updatePanel1_Init"

đến tập tin 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); 
    } 
} 

Cảm ơn bạn mọi người khác trong chủ đề này tôi bắt đầu.

2

Đây là cách duy nhất tôi có thể làm cho bảng cập nhật của mình hoạt động trong một webpart tương thích hơn/chia sẻ 2007/2010. Chúng tôi sử dụng trang cái năm 2010 với trình quản lý tập lệnh nhưng trang cái năm 2007 không có trang chủ.

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

tôi đã sử dụng mã này trong các điều khiển web tùy chỉnh (cs) có chứa bản cập nhật tấm.

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); 
    } 
    //... 
} 
Các vấn đề liên quan