2009-10-29 100 views
1

我有一個列表框控件。當用戶點擊它時,它會告訴自定義控件使用某個ID來使用。解決視圖狀態/命名空間衝突

自定義控件每次(動態)繪製相同的東西,只是根據這個ID加載不同的內容(它從數據庫加載到控件等動態表單中)。

好吧,現在我在查看狀態溢出時遇到了麻煩。當你點擊列表框加載說ID#1時,它會看起來很好。然後,您單擊ID#2,並且在自定義控件中創建的所有文本框控件都具有放入ID#1的相同內容。所以當列表框索引發生變化時,我需要清除視圖狀態,但是我無法使其工作。

所有的控件都是在Page_Load中創建的。

我試過Page_Load的ViewState.Clear(),但是沒有做任何事情。

我有從INamingInterface派生的自定義控件,但我猜ID仍然匹配viewstate。我試過改變自定義控件ID爲獨特的東西(如「CONROL _」+ id.ToString())我也試着做與包含自定義控件面板相同的事情。

我似乎無法擺脫這種觀點狀態!

編輯 確定這裏是代碼演示該問題

public partial class _Default : System.Web.UI.Page 
{ 
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (ddl.SelectedValue == "1") 
    { 
     Create("ID #1"); 
    } 
    else if (ddl.SelectedValue == "2") 
    { 
     Create("ID #2"); 
    } 
} 
void Create(string text) 
{ 
    TextBox t = new TextBox(); 
    t.Text = text; 
    pnl.Controls.Add(t); 
} 
} 

標記:

<div> 
    <asp:Panel ID="pnl" runat="server"> 
     <asp:DropDownList ID="ddl" runat="server" AutoPostBack="True"> 
     <asp:ListItem Text="id 1" Value="1"> 
     </asp:ListItem> 
     <asp:ListItem Text="id 2" Value="2"></asp:ListItem> 
     </asp:DropDownList> 
    </asp:Panel> 
</div> 

如果你運行這段代碼,你會發現,如果你改變什麼是在文本框和那麼你改變下拉列表,那麼你之前輸入的內容將保留在那裏而不是被覆蓋。

我的基本目標是得到它,所以當你改變ID#2時,它會把「ID#2」放在文本框中,不管怎樣(最好不要禁用視圖狀態)

+0

你可以添加一些代碼來說明我們你的問題? – 2009-10-29 16:56:15

+0

這對你有幫助嗎? – Earlz 2009-10-29 18:14:32

回答

1

如果我設置了Text控件的ID,那麼它不會保留舊的價值。你是否給所有控件一個唯一的ID?

void Create(string text) 
{ 
    TextBox t = new TextBox(); 
    t.ID = text; 
    t.Text = text; 
    pnl.Controls.Add(t); 
} 
+0

不是每個控件,因爲50-75都是動態創建的。有沒有辦法得到它,所以我可以把它包裝在一個INamingContainer中,並給它一個唯一的ID,因爲做這麼大的重構只是爲了給通用字段提供無意義的ID似乎是錯誤的 – Earlz 2009-10-29 21:18:28

+0

自定義控件應該實現INamingContainer界面,然後您動態創建並希望正確更新的所有控件在自定義控件中都應該有一個unqiue ID。 – 2009-10-29 21:46:57

+0

儘管它很痛苦,但它完全修復了回發問題(如何在OnLoad之後將控件恢復到回發值)...現在,只需將ID添加到代碼中的大約40或50個控件中即可。 – Earlz 2009-10-30 19:39:24

0

你不能這樣做。

爲了viewstate正常工作,所有的控件必須在它被加載並且使用相同的id之前被創建。因此,您必須將控件定義存儲在會話中,然後重新創建,然後使用與ASP.NET相同的ID從視圖狀態加載它們的屬性。 Page_load太晚了,請在PreLoad上執行。

但在設計時創建的所有控件的可見性設置爲false會更容易,並且交替顯示它們的可見性,以便viewstate可以正常工作。

+0

我們不能將整個控件做成不可見的東西,因爲這需要一次將數千個動態控件從數據庫中載入(當時它在一個頁面上一次只能控制30-50個)。我們無法將其更改爲使用PreLoad 1.因爲它位於Web部件中,所以事件不可用,以及2.我們無法在Page_Init中使用它,因爲viewstate不適用於下拉列表。 – Earlz 2009-10-29 22:04:21

+0

我認爲你創建一個服務器控件會更好,在那裏你將擁有所有的自由度來定義將在視圖狀態下保存的內容。 – Wagner 2009-11-11 14:38:36

0

其實這已不再相關。我們通過爲我們的動態創建的控件禁用viewstate來修復它。這在所有情況下都不起作用,但在我們的例子中,用戶可以推送兩個按鈕(用於動態控件)或者用於切換表單的列表框。這兩個按鈕都將控件的狀態保存到數據庫,所以viewstate實際上並不需要。(我總是在思考viewstate時以及它如何與控件交互時感到困惑。)

所以基本的建議:如果你在控制視圖狀態時遇到麻煩,確保你確實需要它。

+0

等待,實際上它不工作禁用viewstate ..所以它不是一個視圖狀態問題...... *投票結束* – Earlz 2009-10-30 19:11:24