2009-07-24 78 views
21

我發現在用戶控件中持久化屬性值的唯一方法是使用ViewState。用戶控件(ascx)和屬性

public string Title { 
     get { return Convert.ToString(ViewState["Title"]); } 
     set { ViewState["Title"] = value; } 
    } 

我不能說我這個真正深刻的印象,雖然,作爲一種屬性的用戶控件具有更多的廢話,你會在ViewState貼敷。有更好的方法來堅持房地產嗎?

+3

所有Web控件以相同的方式執行此操作,這就是爲什麼ViewState變得非常龐大... – 2009-07-24 20:57:11

+0

我不得不最終訴諸於此。這是相當令人沮喪的,它如何工作,但它的工作..現在.. .. :) – 2012-09-21 07:50:59

回答

10

這取決於。如果您需要將屬性值持續保存在回傳之後,那麼您必須使用ViewState或Session。由於這些控件是在每個帖子後面重新創建的,因此您無法真正保持該狀態。

+0

是的,屬性值需要堅持通過回傳。我在用戶控件中有一個按鈕,點擊按鈕(duh)時會引發按鈕事件,並且此時我需要檢索某些屬性值。哦,猜猜我只會膨脹ViewState! 「 – Jagd 2009-07-24 19:40:28

-1

你有沒有試過靜態屬性?另外,請記住http是無狀態的,所以你可以重新設置你的標題page_load

2

這並不是太糟糕 - 這幾乎是內置控件的工作方式,通常會導致預期的行爲。最好的辦法是在不需要在回傳中保留這些值的情況下,選擇性地禁用ViewState。

你也可能想看看ControlState - 它是一個單獨的「包」,人們不能禁用,並用於像GridView的東西,有些東西,不能通過視圖狀態關閉因爲它打破了控制。

5

你的問題正是ViewState的目的:要持續跨回發控件的屬性,所以你的解決方案就好了。

你可以將它保存在會話中,但這真的只是把負擔放在服務器上。根據您擁有的用戶數量,這可能會很快變得非常難看。

另外請記住,如果你使用會話你必須做一些家務。例如,如果要在同一頁上使用兩次用戶控件,則需要確保每個控件都使用唯一的會話變量。

8

使用ViewState存儲用戶控件的屬性值完全沒有問題。

雖然你的陳述「用戶控件擁有更多的屬性,你會堅持在ViewState中更多的屬性」並不一定是真的。當然,ViewState可以跟蹤控件的屬性值,但不會將數據存儲在隱藏表單字段變量__VIEWSTATE中。

聽起來很瘋狂吧?有關ViewState如何工作的精彩文章,請參閱TRULY Understanding ViewState

這取決於您初始化控件在其生命週期中的屬性。在控件的StateBag開始跟蹤對屬性值的更改後,ViewState將只存儲在隱藏的__VIEWSTATE字段中。這種情況發生在OnInit方法中,該方法處於生命週期的早期階段,但有些技術可以提前設置屬性值,但不會產生__VIEWSTATE膨脹的成本,並且仍會爲您提供所有好處。

查看鏈接的文章。它討論一切都非常清楚,比我能:-)

0

你總是可以覆蓋打算SaveViewState/LoadViewState方法:

public string Title { get; set; } 

,然後保存並負載要求:

protected override object SaveViewState() 
{ 
    // Save State as a cumulative array of objects. 
    object baseState = base.SaveViewState(); 

    object[] allStates = new object[2]; 
    allStates[1] = _title; 
    return allStates; 
} 

protected override void LoadViewState(object savedState) 
{ 
    if (savedState != null) 
    { 
     // Load State from the array of objects that was saved during SavedViewState. 
     object[] myState = (object[])savedState; 
     if (myState[0] != null) 
     base.LoadViewState(myState[0]); 

     if (myState[1] != null) 
     _title = (String)myState[1]; 
    } 
}