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>

相关文章
相关标签/搜索