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

<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. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...

  2. Nova PhoneGap框架 第五章 文件结构

    一个好的项目架构必然有着合理的文件结构,如果一个项目的文件组织混乱,那么可以断言一定是项目架构有问题. 合理的文件结构能够帮你更清晰的管理你的文件,并且当需要添加新的文件的时候,你的程序员很清楚应该加 ...

  3. Entity Framework Code First数据库连接

    1. 安装Entity Framework 使用NuGet安装Entity Framework程序包:工具->库程序包管理器->程序包管理器控制台,执行以下语句: PM> Insta ...

  4. 当MyEclipse突然异常关闭

    今天的博文主要记录一个问题,就是当MyEclipse异常关闭后,再次开启环境,导致Tomcat无法启动的问题解决方案 问题描述:在MyEclipse启动或者是tomcat启动的时候出现:Address ...

  5. Oracle没有WM_CONCAT函数的解决办法

    WM_CONCAT是oracle的非公开函数,并不鼓励使用,新版本oracle并没有带此函数,需要手工加上. 1.下载三个文件:owmctab.plb  . owmaggrs.plb . owmagg ...

  6. 拓展 Android 原生 CountDownTimer 倒计时

    拓展 Android 原生 CountDownTimer 倒计时 [TOC] CountDownTimer 在系统的CountDownTimer上进行的修改,主要是拓展了功能,当然也保留了系统默认的模 ...

  7. salesforce 零基础学习(四十六)动态美观显示列表中记录的审批状态

    项目中,申请者申请某些事项以后,常常需要在申请列表中查看当前申请的记录所在的审批状态,动态美观的显示状态可以使UI更符合客户要求,比如下面这样. 以Goods__c表为例,申请者申请的一些采购以前需要 ...

  8. 基于1.3.3版本tooltip的datagrid单元格tip实现

    基于1.3.3版本tooltip的datagrid单元格tip实现 2013年05月25日 ⁄ datagrid ⁄ 共 6122字 ⁄ 评论数 26 ⁄ 被围观 7,033 views+ 文章目录 ...

  9. 学习3ds max插件开发过程中的一些小结

    1. 3ds max是以树状结构来管理整个场景的,每个树节点类型为INode 2. Interface类很关键,可以通过其中的GetRootNode.NumberOfChildren和GetChild ...

  10. Npoi导出Excel 实战篇(Webform)

    开篇语 废话不多说,直接上遇到的问题 需求:在这个界面点击导出,导出页面数据,苦于没有做过webfrom项目,弄了半天还是没想到原生态的好方法,所以在网上看了下有没有导出的好例子,结果发现有人推荐使用 ...