複雜屬性和狀態管理
複雜屬性聲明/持久:
所謂複雜屬性,即通常不可用CLR的基礎資料型別 (Elementary Data Type)表達的屬性。譬如,FontInfo,即代表字型屬性,包含Bold 、Name、Size、Color等資訊(通常稱為子屬性)。
對於複雜屬性,控制項在聲明時候,通常採用 屬性—子屬性 的連字號表示複雜屬性的一個子屬性。
<sdp:TextBox id=”Textbox1” Font-Name=”Vender” Font-Size=”12pt” runat=”server” />
其中的劃線部分即代表了Font屬性。
複雜屬性的另外一種表達是,將複雜屬性嵌套放於控制項聲明標籤之中,乘坐 內部屬性持久性(inner property persistence )。如:
<asp:DataGrid runat=”Server”>
<HeaderStyle ForeColor=”Red” />
</asp:DataGrid >
複雜屬性序列化/持久化的設計時支援
設計時實現是在控制項之外實現的,利用中繼資料(attribute)來實現。對於連字號實現的子屬性,經過設定特定的attribute,即可影響設計器從而實現設計時支援。
DesignerSerializationVisibility 實際上在asp.net中是指DesignerSerializationVisibilityAttribute的屬性類,通過中繼資料中指定,並且設為:
DesignerSerializationVisibility.Content可以讓設計器知道,應當將複雜屬性的內容進行序列化而不是屬性本身
DesignerSerializationVisibility.Hidden 讓設計器忽略屬性和屬性內容
DesignerSerializationVisibility.Visible 讓設計器以正常方式序列化
所謂正常方式,就是以字元傳、整型如果不屬於這些就用位元組方式持久化屬性(當然對於複雜屬性這相當划不來)。
NotifyParentProperty(true) 表示屬性瀏覽器對控制項得此複雜屬性的修改可以通告給控制項,並告知之上的各個對象(通常會給設計器應用程式),告知屬性已經“髒”了。這些約定對控制項設計者和設計器開發人員以及asp.net頁面的開發人員都很重要。
對於標籤嵌套方式的屬性持久,應當採用ParseChilren(true)來指定屬性的持久,設計器實現嵌套方式則應當指定PersistChildren(false)讓設計器將嵌套標籤轉化為複雜屬性的一部分(而不是內嵌的子控制項)
類型轉換器
為瞭解讀複雜屬性的持久形式為設計運行時形式,需要對複雜屬性指定類型轉換器,基本目標是將持久形式解讀轉換為CLR支援的類型,同時也將屬性的CLR類型表達為設計時、運行時的持久形式。即將Font-Size=”8pt”轉換為int32 的8,將複雜屬性的8持久化為Font-Size=”8pt”.
類型轉換器的實現不依賴於任何使用者介面功能。因此,可在 Windows 表單和 Web Form中應用同一個類型轉換器。
類型轉換器繼承自System.ComponentModel.TypeConverter。
實作類別型轉換器的步驟:
1、 定義一個從 System.ComponentModel.TypeConverter 派生的類。
2、 重寫 CanConvertFrom 方法,指定轉換器可從中轉換的類型。此方法是重載方法。
3、 重寫實現轉換的 ConvertFrom 方法。此方法是重載方法。
4、 重寫 CanConvertTo 方法,指定轉換器可轉換為的類型。轉換為字串類型不需要重寫此方法。此方法是重載方法。
5、 重寫實現轉換的 ConvertTo 方法。此方法是重載方法。
6、 重寫執行驗證的 IsValid 方法。此方法是重載方法。
通過TypeConverter(typeof(somecustimoziedTypeConverter))的方式確定某個屬性同特定的類型轉換器相關。
對於asp.net應用來講,如何保持兩個頁面間的控制項的複雜屬性很重要。Control類的預設狀態管理交給ViewSatte字典,而複雜屬性,使用ViewState時不可能的,這必須用到IstateManager介面參與狀態管理。
Interface IstateManager
{
public bool IsTrackingViewState ; //當由類實現時,擷取一個值,通過該值指示伺服器控制項是否正在跟蹤其檢視狀態更改。
void LoadViewState( object state); //當由類實現時,載入伺服器控制項以前儲存的控制項檢視狀態。
object SaveViewState(); //當由類實現時,將伺服器控制項的檢視狀態更改儲存到 Object。
void TrackViewState();//當由類實現時,指示伺服器控制項跟蹤其檢視狀態更改。
}
Control的ViewSatte屬性實際上就是一個複雜屬性,本質上是一個字典類,通過實現了IstateManager介面參與狀態管理(ViewState的細節):
1、 ViewState的資料類型是複雜屬性System.Web.UI.StateBag類。實現IstateManager介面的字典。儲存多項鍵/值對,鍵為字串,值為對象,當某個對象自動添加到State把執行個體即ViewState中去時,自動加入一個StateItem對象,存有實際的屬性值和相關的布爾標誌,知識此屬性(StateItem)在初始化後修改過。
2、 在介面的TrackViewState中將此函數的值對應到StateBag的內部布爾變數,如果為真,則當StateItem添加時候(跟蹤一個對象的ViewState),或者修改行為,都將StateItem標記為修改過。
3、 SaveViewSate中,枚舉項目,建立並返回兩個ArrayList分別標記修改過的鍵和值。
4、 LoadViewSatet執行SaveState的逆操作。
當在ViewSatte中儲存屬性時候,其狀態會自動維護。可以在ViewState中儲存任何控減災往返傳送時需要的數(而不是全部資料,從效率考慮剔除冗餘資料),且任何儲存在ViewState紅的資料必須時通過LosFormatter序列化的
所有複雜屬性的狀態儲存應當實現IstateManager來將複雜屬性轉換為可以在ViewState中儲存的簡單屬性,並且也可以ViewState中儲存的簡單屬性恢複組合為複雜屬性。