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, ...
随机推荐
- Apache许可协议Open RIA Services
Jeff Handley's进行了多年的项目--基于一份开源许可发布WCF RIA Services.遵循Apache 2许可,捐赠给Outercurve基金会的ASP.NET Open Source ...
- Understand Lambda Expressions in 3 minutes(翻译)
本文翻译自CodeProject上的一篇简单解释Lambda表达式的文章,适合新手理解.译文后面我补充了一点对Lambda表达式的说明. 1.什么是Lambda表达式? Lambda表达式是一种匿名方 ...
- 浅析MSIL中间语言——PE文件结构篇
一.开篇 开篇我想讲一下于本文无关的话题,其实我很想美化一下自己博客园一直没时间弄,无意间找了博客园李宝亨的博客园里面有一篇分享自己主题的文章,我就将这个模板暂时用作我的blog主题,我要讲述一个关于 ...
- fir.im Weekly - 让 iOS 应用更加安全
攻易防难,关于 iOS 应用安全看起来有些神秘.iOS Security , 源于@吴发伟_则平博客翻译的关于iOS安全的一系列文章,现在站点已经系统收集了大量关于 iOS 逆向.安全.反编译.静动态 ...
- 【最后的抒情】【离NOIP还有9个小时】
学了NOIP 大概十一个月左右,中途的插班生.从2015年12月底开始学信息竞赛,在寒假的时候还笑着我还有九个月才考试呢,生竞就只有两个月了.没错我是从生物竞赛转过来的.记得当初写申请的时候,写的理由 ...
- 深入理解javascript对象系列第二篇——属性操作
× 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...
- .Net 转战 Android 4.4 日常笔记(8)--常见事件响应及实现方式
在Andrioid开发中,常见的事件如下 单击事件 OnClickListener 长按事件 OnLongClickListener 滑动事件 OnTouchListenner 键盘事件 OnKeyL ...
- 如何用Perl截取报文
在实际生产环境中,常常需要从后台日志中截取报文,报文的形式类似于 <InterBOSS> ... ... ... </InterBOSS> 一个后台日志有多个报文,每个报文可由 ...
- EF CodeFirst EntityTypeConfiguration 自关联映射配置
实体示例代码: public class Message { public Message() { } public int ID { get; private set; } public strin ...
- js简单操作Cookie
贴一段js简单操作Cookie的代码: //获取指定名称的cookie的值 function getCookie(objName) { var arrStr = document.cookie.spl ...