Build 2015圆满落幕了,不知大家有多少人刷夜看了直播呢?不管怎么说,想必各位都很好奇在这场微软开发者盛宴上,Microsoft又发布了什么令人惊叹的消息吧。笔者略微整理了一些与UWP相关的内容,抛砖引玉,并不全面,希望读者多多指正。
(文章中涉及的图片均来源于Build)
作为全新的应用类型,UWP自然有了全新的开发框架。用C#+XAML来说,基本保持了UAP的开发模式,但是新增了诸多特性。在这里简单为大家列举一二。
在UWP中,由于没有平台区别,几乎所有控件都成为跨平台控件了,而非UAP下不同平台的使用限制。其中值得注意的一些新控件有:
由于UWP将面对复杂多变的应用分辨率,曾经为一些固定分辨率设计页面的日子一去不复返。从这点来说,UWP也更靠近网页设计一些。可是对于html,我们有relative、有流式布局;XAML呢,总不能老是把自适配实现在csharp代码里吧?别急,XAML足够做绝大部分的工作。且看:
这是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>
如果使用熟练,其能发挥的作用异常强大。
可能有读者会疑惑了:即使有很强大、可自定义的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的属性设置,它们能带来极灵活的页面行为,足够满足大部分页面布局需求,只有少部分相当定制化的页面行为需要书写代码了。
对于大家日常使用的控件,在不同设备上运行时也有不同的效果,它们是微软专门设计以适配不同操控类型、屏幕大小设备,从这一点来说,可以省去页面设计者不小功夫。如:
新的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的囊中之物。那么究竟有什么改动呢?
想获得更多有关Build的展示情况,请访问
http://channel9.msdn.com/events/build/2015?Media=true&wt.mc_id=build_hp
查看更多展示的视频和ppt吧。