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

<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 Core中遭遇循环依赖问题"A circular dependency was detected"

    今天在将一个项目迁移至ASP.NET Core的过程中遭遇一个循环依赖问题,错误信息如下: A circular dependency was detected for the service of ...

  2. 使用 nvm 管理不同版本的 node 与 npm

    补充说明:Mac 下通过 brew install nvm 所安装的 nvm ,由于安装路径不同,无法正确启用.建议使用 brew uninstall nvm 卸载掉之后,通过本文的方案重新安装一次. ...

  3. 七天学会ASP.NET MVC (四)——用户授权认证问题

    小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...

  4. 控制Linux下 mono 服务的启动停止

    当Window下的服务部署到Linux的时候,我们一般用Mono.service 来启动停止.参数比较多,不太好用.于是有个这个Shell脚本. 用法:moa s1 start #启动         ...

  5. [大数据之Spark]——快速入门

    本篇文档是介绍如何快速使用spark,首先将会介绍下spark在shell中的交互api,然后展示下如何使用java,scala,python等语言编写应用.可以查看编程指南了解更多的内容. 为了良好 ...

  6. 2013 duilib入门简明教程 -- VS环境配置(2)

        既然是入门教程,那当然得基础点,因为搜索duilib相关资料时,发现有些小伙伴到处都是编译错误,以及路径配置错误等等,还有人不知道SVN,然后一个个文件手动下载的.     其实吧,duili ...

  7. iOS-----Crash文件分析(一)

    开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退.脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断.联想起老罗在发布Smartisan ...

  8. 在drawable 画胶囊状

    <solid android:color="@color/colorAccent"></solid> <corners android:radius= ...

  9. Exception:HTTP Status 500 - org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

    主要错误信息如下: HTTP Status 500 - org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...

  10. c++头文件 #include<iostream>

    cout<<"C1="<<setiosflags(ios::fixed)<<setprecision(2)<<3.14*r*2< ...