2010-02-12 92 views
6

我有一個ViewState的問題。我有一個aspx頁面,左側有一個treeview,右側有一個ASP.NET面板的UpdatePanel。它在內部面板,我加載和卸載動態用戶控件。我使用該更新面板來加載動態控件。Viewstate變量在用戶控件上動態加載丟失

我也爲我的用戶控件做了一個自定義控件,因爲我需要從頁面傳遞一些值。在該構造函數中,我使用ViewState來存儲這些值。

我第一次加載用戶控件時,我用參數調用它的構造函數。當我重新加載每個回發用戶控件時,我使用它的正常構造函數。

我的問題是我存儲在ViewState中的值在連續回發中變爲空值。

更新:

這是一張我的用戶控制的:

public class MyUserControl : System.Web.UI.UserControl 
{ 
private int PKId 
{ 
    get { return ViewState["pkId"] as int; } 
    set { ViewState["pkId"] = value; } 
} 

public MyUserControl(int pkId) 
{ 
    this.PKId = pkId; 
} 

... 
} 

我下面這篇文章,以動態地加載控件:http://msdn.microsoft.com/en-us/magazine/cc748662.aspx#id0070065

第二更新:
我還設置同一控制ID當我加載在第一時間和在每個reaload用戶控制。

也許我可以使用另一種方法來存儲這些值,如輸入隱藏字段或緩存。我選擇ViewState是因爲我不想用每個用戶的Session值超載服務器。

第三次更新:

I load the controls with this code: 

System.Web.UI.UserControl baseControl = LoadControl(ucUrl) as System.Web.UI.UserControl; 
if (baseControl != null) 
{ 
    baseControl.ID = "DestinationUserControl"; 
    PanelDestination.Controls.Add(baseControl); 
} 

而且reaload與此代碼:

DynamicControls.CreateDestination ud = this.LoadControl(TrackedUserControl) as DynamicControls.CreateDestination; 
if (ud != null) 
{ 
    ud.ID = "DestinationUserControl"; 
    PanelDestination.Controls.Add(ud); 
} 

發生了什麼事?

+0

請提供一些這樣做的代碼,以便我們可以更好地瞭解正在發生的事情。 – 2010-02-12 16:05:52

+0

我已更新該問題。 – VansFannel 2010-02-12 16:46:14

+0

爲什麼在初始加載時將它作爲UserControl鍵入,並在重新加載時作爲CreateDestination? – 2010-02-13 09:58:44

回答

3

嘗試將控件存儲到局部變量中,一旦在控件層次結構中添加/構造控件之前將其加載/構建。這允許ViewState數據從控件映射到控件。請參閱「規則2」http://chiragrdarji.wordpress.com/2009/05/20/maintain-viewstate-for-dynamic-controls-across-the-postback/

+0

我在這兩種情況下都設置了相同的ID,它不起作用。 – VansFannel 2010-02-13 07:17:24

+1

啊,好的。我的答案已更新。這應該做到這一點。 – 2010-02-13 07:26:54

+0

也許我不明白你的答案,但我正在按照規則2那樣做。我更新了我的問題,並提供了更多細節。 – VansFannel 2010-02-13 09:18:26

0

在UpdatePanel中動態添加控件是一個壞主意。它產生了很多問題。

如果可能的話,將動態控件創建移出UpdatePanel,我相信你的問題將得到解決。

+0

我很抱歉。我犯了一個錯誤。它是一個帶ASP.NET面板的UpdatePanel。它在內部面板,我加載和卸載動態用戶控件。 – VansFannel 2010-02-12 18:02:28

3

何時加載用戶控件?如果您希望ViewState被保存/恢復,則必須在Init事件中發生。

+0

用戶控件有一些文本框。如果他們有一些文本,它會在回發中正確恢復。我正在重新加載Page_Load事件中的用戶控件。我正在關注這篇文章來動態地加載控件:http://msdn.microsoft.com/en-us/magazine/cc748662.aspx#id0070065 – VansFannel 2010-02-13 05:47:32

+2

如果那篇文章說在Page_Load中加載動態控件,它只是平坦的錯誤。這在某些情況下會起作用,但當然不是全部,就像您發現的那樣。 ViewState還原發生在Page_Load之前,這就是爲什麼你的變量爲空。沒有簡單的方法來解釋它。 – Bryan 2010-02-13 22:15:53

0

由於Bryan提到,你應該在Page_Init中加載動態控件而不是Page_Load。

正如this description of the Page Life Cycle所解釋的,在Page_Load事件發生的時候,回發中的視圖狀態已經被處理(在PreLoad中)。如果控件還沒有重新加載,視圖狀態就無處可去。

預緊:

使用,如果您需要在Load事件之前,你的頁面或控制 執行 處理此事件。

頁面實例引發此事件 之前,它加載視圖狀態本身 和所有控件,然後處理包含在 Request實例 任何回發數據。

+0

也許我可以使用另一種方法來存儲這些值,如輸入隱藏字段或緩存。我選擇了ViewState是因爲我不想超載服務器。 – VansFannel 2010-02-13 07:19:43

+0

控件可以在Load事件中回發時動態添加,屆時其生命週期將「趕上」當前事件。請參閱http://msdn.microsoft.com/en-us/library/ms178472.aspx和此處的演練#6的「追加控件的追趕事件」http://www.codeproject.com/KB/aspnet/ aspnetviewstatepagecycle.aspx#演練(很好地說明了在控制添加到層次結構之前和之後的行爲差異)。 – 2010-02-13 07:22:40

+0

@gWiz,而演練#6很有趣,取決於「追趕」事件充其量是有問題的。即使演練本身也說「建議您在」PreInit「或」Init「事件期間添加動態控件。這就是我對@VansFannel的建議。 – 2010-02-13 17:48:33