UWP?UWP! - Build 2015有些啥?
Build 2015圆满落幕了,不知大家有多少人刷夜看了直播呢?不管怎么说,想必各位都很好奇在这场微软开发者盛宴上,Microsoft又发布了什么令人惊叹的消息吧。笔者略微整理了一些与UWP相关的内容,抛砖引玉,并不全面,希望读者多多指正。
(文章中涉及的图片均来源于Build)
4. UWP开发框架的新特性
作为全新的应用类型,UWP自然有了全新的开发框架。用C#+XAML来说,基本保持了UAP的开发模式,但是新增了诸多特性。在这里简单为大家列举一二。
新加入的通用控件
在UWP中,由于没有平台区别,几乎所有控件都成为跨平台控件了,而非UAP下不同平台的使用限制。其中值得注意的一些新控件有:
- Pivot:是的,就是大家耳熟能详的Pivot,现在可以在所有平台使用了。区别在于在大屏环境下其行为、展现方式会有略微不同。
- AutoSuggestBox:有自动补齐功能的搜索框,将替代传统的SearchBox。
- UniversalMaps:跨平台的地图控件,再也不用为不同平台的定位应用设计不同的地图展示逻辑了。
- SplitView: 提供可伸缩的导航栏用于导航容器中的页面,作为一个全新的控件,其具有极高的页面适配性,利用下文介绍的自适配技术可以轻松地让其适配复杂的页面。
- InkCanvas:新封装的控件以支持用户笔记,其应用场景还是很多的,可以省去在这些情况下开发者的不少精力了,毕竟实现一个用户友好的图画版并不轻松。
自适配辅助
由于UWP将面对复杂多变的应用分辨率,曾经为一些固定分辨率设计页面的日子一去不复返。从这点来说,UWP也更靠近网页设计一些。可是对于html,我们有relative、有流式布局;XAML呢,总不能老是把自适配实现在csharp代码里吧?别急,XAML足够做绝大部分的工作。且看:
VisualStateManager
这是XAML的一个元素,其功能,一言以蔽之,就是管理在不同条件下页面各元素的属性以及其切换时过渡方式。我们先看下面的一段代码:
<VisualStateGroup x:Name="WindowSizeStates"> <VisualState x:Name="WideState"> <VisualState.Setters> <Setter Target="splitView.DisplayMode" Value="Inline" /> </VisualState.Setters> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> </VisualState> <VisualState x:Name="NarrowState"> <VisualState.Setters> <Setter Target="splitView.DisplayMode" Value="Overlay" /> </VisualState.Setters> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> </VisualState> </VisualStateGroup>
上述代码的作用是当页面宽度大于720时,将splitView.DisplayMode属性调节为inline;否则为Overlay。其语法和规则都相当简单,只需在不同的VisualState中定义对应的Trigger和Setter即可,如果有需要还可以定义不同State间的切换动画。
其中值得注意的是,Trigger并非只能使用框架给出的指定触发器这么简单,它是可以自定义的,再看下面这个例子:
public class InputTypeTrigger : StateTriggerBase { private FrameworkElement _targetElement; private PointerDeviceType _lastPointerType, _triggerPointerType; public FrameworkElement TargetElement { get { return _targetElement; } set { _targetElement = value; _targetElement.AddHandler(FrameworkElement.PointerPressedEvent, new PointerEventHandler(_targetElement_PointerPressed), true); } } public PointerDeviceType PointerType { get { return _triggerPointerType; } set { _triggerPointerType = value; } } private void _targetElement_PointerPressed(object sender, PointerRoutedEventArgs e) { _lastPointerType = e.Pointer.PointerDeviceType; SetActive(_triggerPointerType == _lastPointerType); } }
其自定义了Trigger,用于判断某个元素的按下类型是鼠标/手指,并在满足条件时触发。我们再看看它在XAML里的用法:
<VisualStateGroup x:Name="InputTypeStates"> <VisualState> <VisualState.StateTriggers> <triggers:InputTypeTrigger TargetElement="{x:Bind ActivityList}" PointerType="Touch" /> <triggers:InputTypeTrigger TargetElement="{x:Bind ActivityList}" PointerType="Pen" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="GoToTopButton.Visibility" Value="Visible" /> </VisualState.Setters> </VisualState> </VisualStateGroup>
如果使用熟练,其能发挥的作用异常强大。
RelativePanel
可能有读者会疑惑了:即使有很强大、可自定义的Trigger,我能做的也不就只有定制一些属性么?如果我想根据具体情况调节位置、尺寸,该怎么办,还是只能诉诸代码么?当然不是:RelativePanel将提供你想要的:
有想过html的流式布局么,有考虑过float一类的css属性在xaml中实现么?RelativePanel正是支持他们的容器。请看下面一段代码:(省略该控件所特化的属性)
<RelativePanel> <Image x:Name="img" …/> <TextBlock x:Name="title" RelativePanel.RightOf="img" RelativePanel.AlignTopWith="img" …/> <TextBlock x:Name="authors" RelativePanel.RightOf="img" RelativePanel.Below="title" …/> <TextBlock x:Name="summary" RelativePanel.RightOf="img" RelativePanel.Below="authors" …/> <Button Content="Download" RelativePanel.RightOf="img" RelativePanel.AlignBottomWithPanel="True" …/> </RelativePanel>
其实际展示效果如下:
看到了其中类似于Rightof/below的属性了吗?这种相对布局方式正式RelativePanel的精髓所在,利用它可以实现零代码达到页面适配,而精通流式布局的网页设计者们更完全可以仅仅利用其就使自己的页面达到网页的适配程度。当然,配合VisualState的属性设置,它们能带来极灵活的页面行为,足够满足大部分页面布局需求,只有少部分相当定制化的页面行为需要书写代码了。
已经进行过设备适配的控件们
对于大家日常使用的控件,在不同设备上运行时也有不同的效果,它们是微软专门设计以适配不同操控类型、屏幕大小设备,从这一点来说,可以省去页面设计者不小功夫。如:
- MenuFlyout控件在鼠标激发和手指激发时的菜单间距并不相同,以给两种操控方式提供最好的用户体验。
- Pivot在不同尺寸屏幕下的选定标签位置有所区别,以方便单手/双手触控。
全新的绑定方式:编译时绑定
新的XAML提供了一种不一样的绑定方式:编译时绑定({x:bind})。其绑定关系将会在编译时得到检查,运行时仅存在他们之间的数据依赖。正因如此,这种绑定在运行时的效率得到了极大的提升。从Build展示的数据来看,其绑定效率、属性修改响应效率以及资源节省度都有了数倍提升。
<DataTemplate x:DataType="model:FileItem"> <Grid Width="200" Height="80"> <TextBlock Text="{x:Bind DisplayName}" /> <TextBlock Text="{x:Bind prettyDate}" /> </Grid> </DataTemplate>
尽管编译时绑定有不能再运行时动态修改、不能绑定style等缺点,但其效率表明这将是数据绑定模式在未来的发展方向。各位拭目以待吧~
界面响应速度全面提升
既然要做UWP了,如果效率本身不够过硬,怎么适应各种多变的部署平台?微软在这方面也是煞费苦心,大幅提升其运行效率和稳定度,以求用UWP替代传统的pe文件作为微软产品主力军。可以在Build展示里窥见UWP风格的Office,可见未来的Office甚至VS都可能是UWP的囊中之物。那么究竟有什么改动呢?
- XAML元素的惰性加载特性:想必大家都听说过一些函数式编程语言中惰性求值的概念,这里这种概念移植到了界面渲染上。惰性载入可以保证更快的程序启动时间和用户在一般情况下操作的响应速度。
- 文字渲染效率提升:UWP渲染文字的效率提升了50%
- 绑定加速:上文已经讲过,此处并不赘述。
- 新增加的Visual Layer访问API将允许开发者碰触一些更底层的渲染机制,从而在实现动画、变换等操作时拥有更高的效率。
5. 能不能更给力一点?
想获得更多有关Build的展示情况,请访问
http://channel9.msdn.com/events/build/2015?Media=true&wt.mc_id=build_hp
查看更多展示的视频和ppt吧。