mobileControls与移动控件适配
此配置节的作用在于指定各种控件在不同类型的移动设备显示的适配器,以达到适应各种设备不同的展示形式。例子如下,
<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的谓词方法

了解设备适配器选择过程
下面的过程描述如何选择页的设备适配器集:
- 按照 Web.config 文件中 <device> 节的定义,ASP.NET 循环访问设备适配器集的集合。 首先检查与所请求的页最接近的 Web.config 文件,然后依次检查在配置层次结构中处于更高位置的各个 Web.config 文件。 最后检查 Machine.config 文件。
- 使用 predicateClass 和 predicateMethod 特性来计算每个设备适配器集的关联谓词。
- 每个谓词使用所提供的 HttpContext 对象来检查目标设备的设备功能,并返回 true 或 false 来指示设备适配器集是否适用。
- 只要有任何谓词返回 true,即认为该设备适配器集是被选定的。 此时,系统使用 <device> 元素的 pageAdapter 特性来确定创建哪个类的实例并创建适配器。
- 如果 Web.config 文件中的谓词都没有返回 true,则将为父目录的 Web.config 文件中的设备适配器集重复此过程。
对于每一个控件,将调用页来提供指定控件类型的设备适配器。 ASP.NET 使用以下步骤来选择适当的控件适配器:
- 所使用的设备适配器集与为页的设备适配器选择的适配器集相同。
- 如果设备适配器集包含直接将控件类映射到设备适配器类的 <control> 元素,则将创建指定适配器类的实例。
- 如果无法直接映射设备适配器集,则将为控件创建基类的新实例。
此过程将一直重复,直至达到基类 Control 为止。 如果在任何时候找到了直接映射,则将创建指定设备适配器类的新实例。 - 如果仍未找到映射,并且设备适配器集从其他适配器集继承,则将为父适配器集重复适配器选择步骤。 此过程将沿着适配器集的层次结构向上执行,直至找到映射。
查找的结果会缓存起来,因此只需要为第一个相关控件执行一次指定的查找。 上述的行为将保留下来。
在 ASP.NET 移动控件及其关联的适配器的生命周期中发生两种类型的交互:控件和设备适配器之间的交互以及页和页适配器之间的交互。
控件和控件设备适配器
在移动控件的生命周期中,在控件及其关联的设备适配器之间发生以下交互:
- ASP.NET 先检查缓存中是否存在页的副本。 如果存在,则将缓存的页发送到客户端。 有关缓存的更多信息,请参见移动文本编写器呈现的最佳做法的"输出缓存"一节。
- 创建控件。 当首次尝试访问控件的 Adapter 属性时,将选择控件适配器并创建它的一个新实例,如适配器映射中的"了解设备适配器选择过程"一节所述。
当创建新适配器时,将设置控件设备适配器的 Control。 - 如果页进行了缓存,则该页将调用适配器以确定缓存是否需要通过任何附加头有所变化。
- 调用控件的 OnInit 方法。 MobileControl 基类的实现调用控件设备适配器的 OnInit 方法。
- 如果存在控件的私有视图状态,则将加载该状态。 如果设备适配器存储了控件的任何设备特定的状态,则 LoadPrivateViewState 方法的 MobileControl 基类实现将调用控件设备适配器的 LoadAdapterState 方法。
- 调用控件的 OnLoad 方法。 MobileControl 基类的实现调用控件设备适配器的 OnLoad 方法。
- 如果控件实现 IPostBackEventHandler 接口并接收回发事件,则调用控件的 RaisePostBackEvent 方法。 如果发送到控件的事件能够根据目标设备有所变化,则此方法的控件实现将调用控件设备适配器的 HandlePostBackEvent 方法。 HandlePostBackEvent 方法返回 true 或 false,指示设备适配器是否已处理事件。
- 如果适用,保存控件的私有视图状态。 如果适配器需要存储控件的任何设备特定的状态,则 SavePrivateViewState 方法的 MobileControl 基类实现将调用控件设备适配器的 SaveAdapterState 方法。
- 调用控件的 OnPreRender 方法。 MobileControl 基类的实现调用控件设备适配器的 OnPreRender 方法。
- 调用控件的 Render 方法。 MobileControl 基类的实现调用控件适配器的 Render 方法。
- 调用控件的 OnUnload 方法。 MobileControl 基类的实现调用控件设备适配器的 OnUnload 方法。
页和页适配器
虽然 MobilePage 类从 .NET Framework Page 类(而不是 MobileControl 类)继承,但 MobilePage 类与适配器相关的行为非常类似于 MobileControl 类的行为。
ASP.NET 中的移动页适配器(例如 ChtmlPageAdapter、HtmlPageAdapter、WmlPageAdapter 或 XhtmlPageAdapter)实现 IPageAdapter 接口(该接口本身实现 IControlAdapter 接口)。 因此,页适配器的大部分生命周期类似于控件适配器的生命周期。 移动页及其设备适配器的交互特定于 Page 类,并且在它们的生命周期中经历以下步骤:
- ASP.NET 创建一个页。 当首次尝试访问页的 Adapter 属性时,将选择页适配器并创建它的一个实例,如适配器映射中的"了解设备适配器选择过程"一节所述。 当创建适配器时,将设置页适配器的 Page 属性。
- 调用页的 OnInit 方法。 MobilePage 基类的实现调用页适配器的 OnInit 方法。
- 调用页的 OnDeviceCustomize 方法。 MobilePage 基类的实现调用页适配器的 OnDeviceCustomize 方法。
- 若要确定页的回发模式(如果适用),则 MobilePage 基类将调用页适配器的 DeterminePostBackMode 方法。 此方法可以检查和修改请求变量。 此方法还负责将任何保持的视图状态信息转换回窗体变量(如果该信息尚未在某个变量中)。
- 如果适用,加载页的私有视图状态。 如果适配器存储页的任何特定于设备的视图状态,则 MobilePage 基类调用页适配器的 LoadAdapterState 方法。
- 调用页的 OnLoad 方法。 MobilePage 基类的实现调用页适配器的 OnLoad 方法。
- 如果适用,保存页的私有视图状态。 如果适配器需要存储页的任何特定于设备的视图状态,则 MobilePage 基类调用页适配器的 SaveAdapterState 方法。
- MobilePage 基类调用页适配器的 SaveViewState 方法。 此方法负责确保作为参数传入的状态被序列化到写入的页。
- 在分页过程中,MobilePage 基类访问页适配器的 OptimumPageWeight 属性。 适配器返回适合目标设备的页权重。
- 调用页的 OnPreRender 方法。 MobilePage 基类的实现调用页适配器的 OnPreRender 方法。
- 创建一个编写器实例用于捕获页输出。 MobilePage 基类调用页适配器的 CreateTextWriter 方法,该方法必须返回特定于目标的文本编写器。
- 调用页的 Render 方法。 MobilePage 基类的实现调用页适配器的 Render 方法。 在呈现过程的某些特定时刻,适配器还负责通过页的 ClientViewState 属性访问并编写页的私有视图状态。
- 调用页的 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与移动控件适配的更多相关文章
- iOS---iOS10适配iOS当前所有系统的远程推送
一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...
- iOS的ATS配置 - 2017年前ATS规定的适配
苹果规定 从2017年1月1日起,新提交的 app 不允许使用NSAllowsArbitraryLoads来绕过ATS(全称:App Transport Security)的限制. 以前为了能兼容ht ...
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- fir.im Weekly - 关于 iOS10 适配、开发、推送的一切
"小程序"来了,微信变成名副其实的 Web OS,新一轮的Web App 与Native App争论四起.程序员对新技术永远保持灵敏的嗅觉和旺盛的好奇心,@李锦发整理了微信小程序资 ...
- iOS开发 适配iOS10
2016年9月7日,苹果发布iOS 10.2016年9月14日,全新的操作系统iOS 10将正式上线. 作为开发者,如何适配iOS10呢? 1.Notification(通知) 自从Notificat ...
- 3D游戏中的画质与效率适配
哪里来的需求? 众所周知,由于不同的设备配置不同.导致其CPU和GPU处理能力有高有低.同样的游戏想要在所有设备上运行流畅且画面精美,是不可能的.这就需要我们针对不同的设备能力进行画质调节,以保证 ...
- iOS 4s-6Plus屏幕自动适配及颜色转换为十六进制
iOS各种屏幕自动适配及颜色转换为十六进制 ★★★XLJMatchScreen自动适配屏幕★★★ 支持pod导入 pod 'XLJScreenMatching', '~> 1.0.3' 如果发现 ...
- Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)
指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...
- 【转载】iOS屏幕适配设计
移动app开发中多种设备尺寸适配问题,过去只属于Android阵营的头疼事儿,只是很多设计师选择性地忽视android适配问题,只出一套iOS平台设计稿.随着苹果发布两种新尺寸的大屏iPhone 6, ...
随机推荐
- 循序渐进做项目系列(5):制作安装包,谁人都可以!——VS制作安装包简明教程
一开始让我做安装包的时候,其实我是拒绝的.因为我根本就不会做安装包.查了资料之后,我很懵,很晕,很乱,因为不清晰,不简明,不直白.然而经过一番彷徨的挣扎,我终于发现:制作安装包,谁人都可以!故挥狼毫, ...
- JavaScript 事件管理
在设计JavaScript xxsdk的时候考虑到能让调用者参与到工作流程中来,开始用了回调函数.如下: this.foo = function(args,callbackFn) { //do som ...
- Javascript本质第一篇:核心概念
很多人在使用Javascript之前都至少使用过C++.C#或Java,面向对象的编程思想已经根深蒂固,恰好Javascript在语法上借鉴了Java,虽然方便了Javascript的入门,但要深入理 ...
- 说说Java程序和数据库交互的乱码解决
本文就本人遇到的问题进行讲解 1.通过jdbc直连方式,连接Mysql数据库,从程序向数据库中写入数据出现的乱码解决方案. 当通过程序向Student表中写入一条数据时,写入数据库的内容会产生乱码. ...
- maven pom中的repository节点配置没有起作用
问题描述 昨天晚上想用spring boot快速搭建一个web开发的项目,就打开spring boot的doc,按照说明开始尝试.没想到出师未捷身先死,第一步就挂了. 以下是spring boot的配 ...
- pl/sql里的exists和in的差别
项目中有个需要需要如下pl/sql(数据库是MariaDB) ) AS small FROM cmp_ent_main a WHERE createTime<'2016-9-21' ,,) ) ...
- 初学者--bootstrap(一)----在路上(1)
bootstrap: 是目前最受欢迎的前端框架,并基于HTML.CSS.JavaScript 等,而且他是为了适应并兼容各个电子设备,是对媒体查询的封装. 1.什么是媒体查询 他 是响应式布局的方 ...
- Android笔记——SQLiteOpenHelper类
public 抽象类 SQLiteOpenHelper 继承关系 Java.lang.Object android.database.sqlite.SQLiteOpenHelper 类概要 这是一个辅 ...
- SQLServer比较两条数据是否相同
SQLServer比较两条数据是否相同 直接比较可能会一个一个字段的比较,也可以将多个字段拼成一个串然后比较,这里有个hash值比较的方法,很好用 用法 将需要的比较的column放进去,逗号隔开,只 ...
- Java基础-输入输出-2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt
2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt ...