2009-07-09 37 views
1

我想在我的UserControl中使用UpdatePanel。問題是控件所在的.aspx頁面不會有ScriptManager。我將需要在UserControl中創建ScriptManager。但是,如果使用UserControl,請在頁面上說兩次,然後放置ScriptManager將不起作用,因爲您只能初始化ScriptManager一次。以UpdatePanel編程式創建ScriptManager的UserControl可能嗎?

在我需要的ScriptManager其他用戶控件(我使用AJAX工具包擴展),我能使用此代碼:

protected override void OnInit(EventArgs e) 
{ 
    base.OnInit(e); 
    Page.Init += new EventHandler(Page_Init); 
} 

void Page_Init(object sender, EventArgs e) 
{ 
    if (Page.Form != null && ScriptManager.GetCurrent(Page) == null) 
     Page.Form.Controls.AddAt(0, new ScriptManager()); 
} 

..worked很大,但不是爲UpdatePanel的情況。

注意,我沒有使用母版頁

(另一種方法我在想的,但不能弄清楚如何做,就是以編程方式創建一個UpdatePanel內的用戶控件)。

+0

只是一方不是,代碼有點「雙」。您重寫OnInit方法並添加一個Init事件處理程序。只需將Page_Init中的代碼放入覆蓋的OnInit? – Colin 2009-07-09 16:50:31

回答

0

我不要認爲這是可能的。我嘗試了幾種不同的方式。您可能需要咬緊牙關,並在頁面中放置腳本管理員。

0

它不起作用的原因是什麼?你是否需要一個ScriptManager的UpdatePanel異常?你在使用System.Web.Extensions 1.0或3.5嗎?我之所以這麼說,是因爲在3.5中對UpdatePanel進行了更改,導致其內容模板在OnInit之前實例化,所以我沒有看到明顯的原因,爲什麼不起作用。如果有異常,看到堆棧跟蹤將會很有幫助。

0

我遇到了同樣的問題。問題是你需要在OnInit階段之前添加腳本管理器 - 就我所見,它需要在初始階段完成。你可以通過加載一個覆蓋來看到這一點 - 我發現頁面通過預置好了,然後去了addedcontrol事件,它在(或剛好在這之後,但這點有道理),「你需要一個腳本管理器「被拋出。我正在努力尋找如何從兒童用戶控件向Page.PreInit事件添加事件處理程序,因爲WUC沒有PreInit事件。即使WUC構造函數在該點之前也不會觸發,並且在構造函數中頁面對象爲null,因此您無法將其添加到此處。即使在WUC的AddedControl階段,您似乎仍然無法訪問主頁面(ScriptManager oSCM = ScriptManager.GetCurrent(Page);返回null),所以如果您似乎無法添加腳本管理器需要,在錯誤被拋出之前。據我所知(在asp.net論壇上我沒有迴應 - 驚喜,驚喜),WUC並沒有開始踢它的方法/事件,直到在父母的預備階段之後,所以有兩種方法可以做到這一點。

1)我認爲我會這樣做的方式是不要在需要腳本管理器的設計器中放置任何內容,並將佔位符放在這些內容需要去的地方。然後在wuc載入中,使用ScriptManager.GetCurrent查看是否已經有一個,然後創建它,如果沒有。然後你動態地添加需要SCM的內容。事情是這樣的: -

 

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="wucTestExample.ascx.cs" Inherits="wucTestExample" %> 

<asp:PlaceHolder ID="plcAJAX" runat="server" /> 
<asp:Label ID="lblGeneral" runat="server" Text="This is another label" /> 

----------------code behind--------------------------- 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

public partial class wucTestExample : System.Web.UI.UserControl 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     ScriptManager oSCM = ScriptManager.GetCurrent(this.Page); 
     if (oSCM == null) 
     { 
      oSCM = new ScriptManager(); 
      oSCM.ID = "scmAJAX"; 
      oSCM.EnablePartialRendering = true; 
      this.plcAJAX.Controls.AddAt(0, oSCM); 
     } 

     UpdatePanel udpMain = new UpdatePanel(); 
     udpMain.ID = "udpMain"; 

     TextBox txtMain = new TextBox(); 
     txtMain.ID = "txtMain"; 
     // other attrbutes here 

     Button btnPostback = new Button(); 
     btnPostback.ID = "btnPostback"; 
     btnPostback.Click += new EventHandler(btnPostback_Click); 
     btnPostback.Text = "Partial Postback"; 

     Label lblPostback = new Label(); 
     lblPostback.ID = "lblPostback"; 
     lblPostback.Text = "initial postback"; 

     udpMain.ContentTemplateContainer.Controls.Add(txtMain); 
     udpMain.ContentTemplateContainer.Controls.Add(btnPostback); 
     udpMain.ContentTemplateContainer.Controls.Add(lblPostback); 

     this.plcAJAX.Controls.Add(udpMain); 
    } 

    void btnPostback_Click(object sender, EventArgs e) 
    { 
     // implement button code here 
     Label lblPostback = (Label)this.plcAJAX.FindControl("lblPostback"); 
     if (lblPostback != null) 
     { 
      lblPostback.Text = String.Format("WUC POstback at : {0}", DateTime.Now.ToLongTimeString()); 
     } 
    } 
} 

然後用它這樣的: -

 

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="TestExampleNoSCM.aspx.cs" Inherits="TestExampleNoSCM" %> 
<%@ Register Src="~/wucTestExample.ascx" TagName="wucTestExample" TagPrefix="ucTE" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> 
    <%--<asp:ScriptManager ID="scmAJAX" runat="server" />--%> 
    <asp:Label ID="lblLoadTime" runat="server" /> 
    <ucTE:wucTestExample ID="wucTestExample" runat="server" /> 
</asp:Content> 

----------------code behind--------------------------- 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

public partial class TestExampleNoSCM : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     this.lblLoadTime.Text = String.Format("Page load at: {0}",DateTime.Now.ToLongTimeString()); 
    } 
} 

所以,如果你對此有何評論或父頁面取消對SCM,世維會仍然仍然可以正常工作。

2)我看到了另一個選項,需要更新面板,程序員在設計器中創建所有控件,然後在頁面加載時環繞它們(在創建SCM之後(如果需要的話)以及UDP和在WUC UDP中添加了所有的控件,然後將其添加到佔位符中,但這樣做會讓我感到非常危險,因爲它似乎是雙重實例化的控件,我想它可能會回來咬他們的屁股。

方法1的缺點是更多的工作是以編程方式在您的updatepanel中創建所有內容,但是如果您確實想要構建一個自我依賴的WUC,那似乎是您的價格(並且希望WUC不應該無論如何,這是複雜的)。我個人認爲在我的應用程序中(因爲WUC不會被使用)我會確保在主頁面上添加所需的SCM。

另外一個,最後,注意我會全情 - 我見過的人說:「把它添加到母版頁」 - 這似乎是一個特別糟糕的主意,恕我直言,除非頁在您的應用程序的需求因爲它會給你的頁面增加一個全新的膨脹水平,並且這似乎不是一個好主意,因爲ASP.NET似乎已經具有良好的膨脹水平...

+0

聽起來像你知道你在做什麼!請讓我知道,如果你找到解決方案! – Darrell 2009-07-29 20:53:28

+0

與我上面的編輯一個警告,以編程方式添加控件可能會增加視圖狀態等級的複雜程度,所以我剛剛添加一個SCM給父母(可能會在控件中提到這個註釋)的boj工作可能是一個「更好」的選擇,除非你需要這個級別或自我依賴/可移植性。 – 2009-08-06 10:31:32

-1

解決方案: you 可以通過檢查當前頁面是否已經包含ScriptManager,在usercontrol中動態添加scriptmanager。以下是如何:)

在用戶控件(ASCX)HTML把這個:

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

而且在後面的代碼(ascx.cs):

//insert Scriptmanager dynamically only IF it does not already exist 
    private void createScriptManager(System.EventArgs e) 
    { 
     // the GetCurrent() method will return a ScriptManager from the Page 
     if (System.Web.UI.AjaxScriptManager.GetCurrent(this.Page) == null) 
     { 
      System.Web.UI.AjaxScriptManager manager = new System.Web.UI.AjaxScriptManager(); 
      manager.EnablePartialRendering = true; 
      pHolder.Controls.Add(manager); 
     } 
    } 

    // call the above method from the usercontrol's OnInit 
    override protected void OnInit(EventArgs e) 
    { 
     // 
     // CODEGEN: This call is required by the ASP.NET Web Form Designer. 
     // 
     createScriptManager(e); 
     base.OnInit(e); 
    } 

有時需要定義ScriptManager動態。在我的情況下,我正在使用一個用戶控件,它將被放入不同的頁面,但其中一些頁面已經包含一個ScriptManager和一些不需要,那麼我的用戶控件如何知道它是否應該定義它自己的ScriptManager?上述代碼的優點在於,只有在頁面上沒有一個腳本管理器的情況下,usercontrol纔會添加腳本管理器。

注意:如果您使用舊版本的Ajax,System.Web.UI.AjaxScriptManager可以替換爲System.Web.UI.ScriptManager。

0

而不是動態地添加一個ScriptManager,如果頁面上不存在的話,簡單地做相反的事情:添加一個ScriptManager到你的ASCX並且如果頁面上已經存在一個ScriptManager,就刪除它。所以......

protected override void OnInit(EventArgs e) { 
    base.OnInit(e); 
    AdjustScriptManager(); 
} 

private void AdjustScriptManager() { 
    if (ScriptManager.GetCurrent(Page) != null) { 
     ScriptManager1 = null; 
    } 
} 

UPDATE:

不,經過進一步的測試,這將無法工作,因爲ScriptManager1 = NULL什麼都不做有益的。如果有辦法做到這一點(或刪除頁面控件),請發表評論。

相關問題