mobileControls與移動控件適配

此配置節的做用在於指定各類控件在不一樣類型的移動設備顯示的適配器,以達到適應各類設備不一樣的展現形式。例子以下, html

<mobileControls sessionStateHistorySize="6"

cookielessDataDictionaryType="System.Web.Mobile.CookielessData">

<device name="XhtmlDeviceAdapters"

predicateClass="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPageAdapter"

predicateMethod="DeviceQualifies"

pageAdapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPageAdapter">

<control name="System.Web.UI.MobileControls.Panel"

adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPanelAdapter" />

<!--其餘控件-->

</device>

   

<device name="HtmlDeviceAdapters"

predicateClass="System.Web.UI.MobileControls.Adapters.HtmlPageAdapter"

predicateMethod="DeviceQualifies"

pageAdapter="System.Web.UI.MobileControls.Adapters.HtmlPageAdapter">

<control name="System.Web.UI.MobileControls.Panel"

adapter="System.Web.UI.MobileControls.Adapters.HtmlPanelAdapter" />

<control name="System.Web.UI.MobileControls.Form"

adapter="System.Web.UI.MobileControls.Adapters.HtmlFormAdapter" />

<control name="System.Web.UI.MobileControls.TextBox"

adapter="System.Web.UI.MobileControls.Adapters.HtmlTextBoxAdapter" />

<!--其餘控件-->

</device>

   

<device name="UpWmlDeviceAdapters"

inheritsFrom="WmlDeviceAdapters"

predicateClass="System.Web.UI.MobileControls.Adapters.UpWmlPageAdapter"

predicateMethod="DeviceQualifies"

pageAdapter="System.Web.UI.MobileControls.Adapters.UpWmlPageAdapter">

</device>

   

<device name="WmlDeviceAdapters"

predicateClass="System.Web.UI.MobileControls.Adapters.WmlPageAdapter"

predicateMethod="DeviceQualifies"

pageAdapter="System.Web.UI.MobileControls.Adapters.WmlPageAdapter">

<control name="System.Web.UI.MobileControls.Panel"

adapter="System.Web.UI.MobileControls.Adapters.WmlPanelAdapter" />

<control name="System.Web.UI.MobileControls.Form"

adapter="System.Web.UI.MobileControls.Adapters.WmlFormAdapter" />

<!--其餘控件-->

</device>

   

<device name="ChtmlDeviceAdapters"

inheritsFrom="HtmlDeviceAdapters"

predicateClass="System.Web.UI.MobileControls.Adapters.ChtmlPageAdapter"

predicateMethod="DeviceQualifies"

pageAdapter="System.Web.UI.MobileControls.Adapters.ChtmlPageAdapter">

<control name="System.Web.UI.MobileControls.Form"

adapter="System.Web.UI.MobileControls.Adapters.ChtmlFormAdapter" />

<control name="System.Web.UI.MobileControls.Calendar"

adapter="System.Web.UI.MobileControls.Adapters.ChtmlCalendarAdapter" />

<!--其餘控件-->

</device>

</mobileControls>

 

實際上這也是本配置節的默認配置的精簡版。 web

各個節點和屬性含義以下 緩存

<mobileControls

--指定移動控件是否能夠具備自定義特性。

allowCustomAttributes="true|false"

--定義字典類的類型,該類維護無 Cookie 的 Forms 身份驗證的密鑰。

cookielessDataDictionaryType="System.Web.Mobile.CookielessData"

--定義用於在服務器會話中保存應用程序視圖狀態的歷史記錄的大小。

sessionStateHistorySize="number">

<!—適配器集-->

<device

name="String"

--指定該設備適配器集必須繼承的設備適配器集。

inheritsFrom="String" "

--爲適配器集指定頁適配器的類類型。

pageAdapter="String"

--指定提供計算器謂詞的類類型。

predicateClass="String"

--指定提供計算器謂詞的方法。

predicateMethod="String>

<control

--控件的徹底限定名稱。

name="String"

--設備適配器的徹底限定名稱。

adapter="String" />

</device>

<device...>...</device>

</mobileControls>

 

   

device節點中,經過predicateClass中指定的類裏面的predicateMethod指定的方法來斷定當前這個設備是否適用於本適配器。這裏感受就和deviefilter識別至關相似,下面則是ChtmlPageAdapter的謂詞方法 服務器

瞭解設備適配器選擇過程 cookie

下面的過程描述如何選擇頁的設備適配器集: session

  1. 按照 Web.config 文件中 <device> 節的定義,ASP.NET 循環訪問設備適配器集的集合。 首先檢查與所請求的頁最接近的 Web.config 文件,而後依次檢查在配置層次結構中處於更高位置的各個 Web.config 文件。 最後檢查 Machine.config 文件。
  2. 使用 predicateClass 和 predicateMethod 特性來計算每一個設備適配器集的關聯謂詞。
  3. 每一個謂詞使用所提供的 HttpContext 對象來檢查目標設備的設備功能,並返回 true 或 false 來指示設備適配器集是否適用。
  4. 只要有任何謂詞返回 true,即認爲該設備適配器集是被選定的。 此時,系統使用 <device> 元素的 pageAdapter 特性來肯定建立哪一個類的實例並建立適配器。
  5. 若是 Web.config 文件中的謂詞都沒有返回 true,則將爲父目錄的 Web.config 文件中的設備適配器集重複此過程。

對於每個控件,將調用頁來提供指定控件類型的設備適配器。 ASP.NET 使用如下步驟來選擇適當的控件適配器: less

  1. 所使用的設備適配器集與爲頁的設備適配器選擇的適配器集相同。
  2. 若是設備適配器集包含直接將控件類映射到設備適配器類的 <control> 元素,則將建立指定適配器類的實例。
  3. 若是沒法直接映射設備適配器集,則將爲控件建立基類的新實例。
    此過程將一直重複,直至達到基類 Control 爲止。 若是在任什麼時候候找到了直接映射,則將建立指定設備適配器類的新實例。
  4. 若是仍未找到映射,而且設備適配器集從其餘適配器集繼承,則將爲父適配器集重複適配器選擇步驟。 此過程將沿着適配器集的層次結構向上執行,直至找到映射。

查找的結果會緩存起來,所以只須要爲第一個相關控件執行一次指定的查找。 上述的行爲將保留下來。 post

   

在 ASP.NET 移動控件及其關聯的適配器的生命週期中發生兩種類型的交互:控件和設備適配器之間的交互以及頁和頁適配器之間的交互。 ui

控件和控件設備適配器 spa

在移動控件的生命週期中,在控件及其關聯的設備適配器之間發生如下交互:

  1. ASP.NET 先檢查緩存中是否存在頁的副本。 若是存在,則將緩存的頁發送到客戶端。 有關緩存的更多信息,請參見移動文本編寫器呈現的最佳作法的"輸出緩存"一節。
  2. 建立控件。 當首次嘗試訪問控件的 Adapter 屬性時,將選擇控件適配器並建立它的一個新實例,如適配器映射中的"瞭解設備適配器選擇過程"一節所述。
    當建立新適配器時,將設置控件設備適配器的 Control
  3. 若是頁進行了緩存,則該頁將調用適配器以肯定緩存是否須要經過任何附加頭有所變化。
  4. 調用控件的 OnInit 方法。 MobileControl 基類的實現調用控件設備適配器的 OnInit 方法。
  5. 若是存在控件的私有視圖狀態,則將加載該狀態。 若是設備適配器存儲了控件的任何設備特定的狀態,則 LoadPrivateViewState 方法的 MobileControl 基類實現將調用控件設備適配器的 LoadAdapterState 方法。
  6. 調用控件的 OnLoad 方法。 MobileControl 基類的實現調用控件設備適配器的 OnLoad 方法。
  7. 若是控件實現 IPostBackEventHandler 接口並接收回發事件,則調用控件的 RaisePostBackEvent 方法。 若是發送到控件的事件可以根據目標設備有所變化,則此方法的控件實現將調用控件設備適配器的 HandlePostBackEvent 方法。 HandlePostBackEvent 方法返回 true 或 false,指示設備適配器是否已處理事件。
  8. 若是適用,保存控件的私有視圖狀態。 若是適配器須要存儲控件的任何設備特定的狀態,則 SavePrivateViewState 方法的 MobileControl 基類實現將調用控件設備適配器的 SaveAdapterState 方法。
  9. 調用控件的 OnPreRender 方法。 MobileControl 基類的實現調用控件設備適配器的 OnPreRender 方法。
  10. 調用控件的 Render 方法。 MobileControl 基類的實現調用控件適配器的 Render 方法。
  11. 調用控件的 OnUnload 方法。 MobileControl 基類的實現調用控件設備適配器的 OnUnload 方法。

頁和頁適配器

雖然 MobilePage 類從 .NET Framework Page 類(而不是 MobileControl 類)繼承,但 MobilePage 類與適配器相關的行爲很是相似於 MobileControl 類的行爲。

ASP.NET 中的移動頁適配器(例如 ChtmlPageAdapterHtmlPageAdapterWmlPageAdapter 或 XhtmlPageAdapter)實現 IPageAdapter 接口(該接口自己實現 IControlAdapter 接口)。 所以,頁適配器的大部分生命週期相似於控件適配器的生命週期。 移動頁及其設備適配器的交互特定於 Page 類,而且在它們的生命週期中經歷如下步驟:

  1. ASP.NET 建立一個頁。 當首次嘗試訪問頁的 Adapter 屬性時,將選擇頁適配器並建立它的一個實例,如適配器映射中的"瞭解設備適配器選擇過程"一節所述。 當建立適配器時,將設置頁適配器的 Page 屬性。
  2. 調用頁的 OnInit 方法。 MobilePage 基類的實現調用頁適配器的 OnInit 方法。
  3. 調用頁的 OnDeviceCustomize 方法。 MobilePage 基類的實現調用頁適配器的 OnDeviceCustomize 方法。
  4. 若要肯定頁的回發模式(若是適用),則 MobilePage 基類將調用頁適配器的 DeterminePostBackMode 方法。 此方法能夠檢查和修改請求變量。 此方法還負責將任何保持的視圖狀態信息轉換回窗體變量(若是該信息還沒有在某個變量中)。
  5. 若是適用,加載頁的私有視圖狀態。 若是適配器存儲頁的任何特定於設備的視圖狀態,則 MobilePage 基類調用頁適配器的 LoadAdapterState 方法。
  6. 調用頁的 OnLoad 方法。 MobilePage 基類的實現調用頁適配器的 OnLoad 方法。
  7. 若是適用,保存頁的私有視圖狀態。 若是適配器須要存儲頁的任何特定於設備的視圖狀態,則 MobilePage 基類調用頁適配器的 SaveAdapterState 方法。
  8. MobilePage 基類調用頁適配器的 SaveViewState 方法。 此方法負責確保做爲參數傳入的狀態被序列化到寫入的頁。
  9. 在分頁過程當中,MobilePage 基類訪問頁適配器的 OptimumPageWeight 屬性。 適配器返回適合目標設備的頁權重。
  10. 調用頁的 OnPreRender 方法。 MobilePage 基類的實現調用頁適配器的 OnPreRender 方法。
  11. 建立一個編寫器實例用於捕獲頁輸出。 MobilePage 基類調用頁適配器的 CreateTextWriter 方法,該方法必須返回特定於目標的文本編寫器。
  12. 調用頁的 Render 方法。 MobilePage 基類的實現調用頁適配器的 Render 方法。 在呈現過程的某些特定時刻,適配器還負責經過頁的 ClientViewState 屬性訪問並編寫頁的私有視圖狀態。
  13. 調用頁的 OnUnload 方法。 MobilePage 基類的實現調用頁適配器的 OnUnload 方法。

大體看了一下上述的流程和網上的源碼,感受每一個移動控件的生命週期只是定立了一個基本的套路,並無具體實現控件在某個具體生命週期內該作的事情,好比拿Calendar控件的渲染Render來講

它直接調用了基類的Render方法,而這個Render調用了OnRender

這裏的Adapter只是一個接口,是從Page中獲取的Adapter,具體的Adapter是從web.config中配置再篩選可得,那就看看具體某個ControlAdapter的Render方法,這裏拿ChtmlCalendarAdapter爲例,內容過長只截取方法頭和部分代碼

看了就知道這確實是實際的渲染控件的代碼。雖然感受這種方式怪怪的,可能也是適配器的做用,可是它確確實實能達到同一個控件在不一樣設備上呈現不一樣樣式的。

 

參考

適配器映射

來自 <https://msdn.microsoft.com/zh-cn/library/w5b9y36y(v=vs.100).aspx>

適配器類型

來自 <https://msdn.microsoft.com/zh-cn/library/99tteheb(v=vs.100).aspx>

適配器與 ASP.NET 的交互

來自 <https://msdn.microsoft.com/zh-cn/library/w5thxd3s(v=vs.100).aspx>

移動文本編寫器呈現的最佳作法

來自 <https://msdn.microsoft.com/zh-cn/library/aa2w58cf(v=vs.100).aspx>

分頁支持

來自 <https://msdn.microsoft.com/zh-cn/library/hhfw2x5a(v=vs.100).aspx>

設備模板支持

來自 <https://msdn.microsoft.com/zh-cn/library/yt1b020d(v=vs.100).aspx>

實現模板呈現

來自 <https://msdn.microsoft.com/zh-cn/library/ah665120(v=vs.100).aspx>

相關文章
相關標籤/搜索