此配置节的作用在于指定各种控件在不同类型的移动设备显示的适配器,以达到适应各种设备不同的展示形式。例子如下,

<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>

实际上这也是本配置节的默认配置的精简版。

各个节点和属性含义如下

<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的谓词方法

了解设备适配器选择过程

下面的过程描述如何选择页的设备适配器集:

  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 使用以下步骤来选择适当的控件适配器:

  1. 所使用的设备适配器集与为页的设备适配器选择的适配器集相同。
  2. 如果设备适配器集包含直接将控件类映射到设备适配器类的 <control> 元素,则将创建指定适配器类的实例。
  3. 如果无法直接映射设备适配器集,则将为控件创建基类的新实例。
    此过程将一直重复,直至达到基类 Control 为止。 如果在任何时候找到了直接映射,则将创建指定设备适配器类的新实例。
  4. 如果仍未找到映射,并且设备适配器集从其他适配器集继承,则将为父适配器集重复适配器选择步骤。 此过程将沿着适配器集的层次结构向上执行,直至找到映射。

查找的结果会缓存起来,因此只需要为第一个相关控件执行一次指定的查找。 上述的行为将保留下来。

在 ASP.NET 移动控件及其关联的适配器的生命周期中发生两种类型的交互:控件和设备适配器之间的交互以及页和页适配器之间的交互。

控件和控件设备适配器

在移动控件的生命周期中,在控件及其关联的设备适配器之间发生以下交互:

  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>

mobileControls与移动控件适配的更多相关文章

  1. iOS---iOS10适配iOS当前所有系统的远程推送

    一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...

  2. iOS的ATS配置 - 2017年前ATS规定的适配

    苹果规定 从2017年1月1日起,新提交的 app 不允许使用NSAllowsArbitraryLoads来绕过ATS(全称:App Transport Security)的限制. 以前为了能兼容ht ...

  3. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

  4. fir.im Weekly - 关于 iOS10 适配、开发、推送的一切

    "小程序"来了,微信变成名副其实的 Web OS,新一轮的Web App 与Native App争论四起.程序员对新技术永远保持灵敏的嗅觉和旺盛的好奇心,@李锦发整理了微信小程序资 ...

  5. iOS开发 适配iOS10

    2016年9月7日,苹果发布iOS 10.2016年9月14日,全新的操作系统iOS 10将正式上线. 作为开发者,如何适配iOS10呢? 1.Notification(通知) 自从Notificat ...

  6. 3D游戏中的画质与效率适配

      哪里来的需求? 众所周知,由于不同的设备配置不同.导致其CPU和GPU处理能力有高有低.同样的游戏想要在所有设备上运行流畅且画面精美,是不可能的.这就需要我们针对不同的设备能力进行画质调节,以保证 ...

  7. iOS 4s-6Plus屏幕自动适配及颜色转换为十六进制

    iOS各种屏幕自动适配及颜色转换为十六进制 ★★★XLJMatchScreen自动适配屏幕★★★ 支持pod导入 pod 'XLJScreenMatching', '~> 1.0.3' 如果发现 ...

  8. Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)

    指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...

  9. 【转载】iOS屏幕适配设计

    移动app开发中多种设备尺寸适配问题,过去只属于Android阵营的头疼事儿,只是很多设计师选择性地忽视android适配问题,只出一套iOS平台设计稿.随着苹果发布两种新尺寸的大屏iPhone 6, ...

随机推荐

  1. .NET WEB程序员需要掌握的技能

    本来这个是我给我们公司入职的新人做一个参考,由于 @张善友 老师在他的微信号转了我的这篇文章<<.Net WEB 程序员需要掌握的技能>>,很多人觉得比较有用,说是看了后知道一 ...

  2. Hadoop学习笔记—1.基本介绍与环境配置

    一.Hadoop的发展历史 说到Hadoop的起源,不得不说到一个传奇的IT公司—全球IT技术的引领者Google.Google(自称)为云计算概念的提出者,在自身多年的搜索引擎业务中构建了突破性的G ...

  3. 搭建 SVN 服务器

    安装.启动 SVN 服务器 在 Windows 下,可以使用以下命令将 SVN 服务注册到 windows 服务中去: sc create svnserver binPath= "drive ...

  4. C/C++ makefile自动生成工具(comake2,autotools,linux),希望能为开源做点微薄的贡献!

      序     在linux下C或C++项目开发,Makefile是必备的力气,但是发现手写很麻烦. 在百度有个comake2工具,用于自动生成Makefile工具,而在外边本想找一个同类工具,但发现 ...

  5. ystep jQuery流程、步骤插件

    今天小菜给大家带来又一款给力jQuery插件:ystep. 从名称上大致可以看出,这是一个流程步骤插件. 如果无意外的话,这可能是小菜近期最后一个作品了...苦逼的小菜即将创业,可能就没时间折腾啦~好 ...

  6. 读书笔记-you-don't-konw-js

    第一部分:作用域和闭包 不要满足于只是让代码正常工作,而是弄清楚为什么是这样 作用域是什么 定义的变量存储在哪里?程序是如何找到变量的?实现的 规则就是作用域 传统编译语言执行前的编译三步骤(p5) ...

  7. SqlServer索引的原理与应用

    索引的概念 索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准,而采用索引来加快数据处理速度通常是最普遍采用的优化方法. 索引是什么:数据库中的索引类似于一本书的目录,在一本书中使用目录 ...

  8. 手动实现jQuery Tools里面tab功能

    平时开发中用的Javascript类库都是jQuery,用到插件或者第三方类库能从jQuery Tools里面找到,基本不用其他的.当然有时同事喜欢使用jQuery UI里面的插件.并且jQuery ...

  9. Web前端框架与类库的思考

    说起前端框架,我也是醉了.现在去面试或者和同行聊天,动不动就这个框架碉堡了,那个框架好犀利. 当然不是贬低框架,只是有一种杀鸡焉用牛刀的感觉.网站技术是为业务而存在的,除此毫无意义,框架也是一样.在技 ...

  10. MySQL学习笔记六:基本DML操作

    1.查询语句,语法如下: SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESUL ...