Visual State Manager,也就是视觉状态管理器并不是Win10的新东西,早在Sliverlight时代就有了。以下简称VSM。
VSM可以根据程序的设置,在设定的条件下更改某些UI的呈现状态。在Win10中因为自适应UI的需求,因此需要VSM的助攻。在Win10中常常可以根据程序的运行环境,或者说运行平台(Phone,Tablet,PC等),或者运行平台的尺寸等各因素修改UI,以达到自适应的目的。
Microsoft Blend 提供了强大的VSM工具。要使用VSM,首先要知道在哪里打开它。有两种方法(实际是一种)
1、打开Blend,打开/新建一个工程,然后打开你要设计的XAML页面。在"状态"面板中就是VSM工具。如果找不到“状态”面板,可以在菜单->视图->状态窗口(Ctrl+Alt+S)中打开。
2、在VS中,在你要设计的XAML页面右键选择“在Blend中设计”,后面的就同1了。
默认的状态面板是空的:
注意右上角有两个Button
第一个作用是添加状态组,各种不同的State就是在基于状态组下的。
第二个的作用是选择是否打开过渡状态。打开之后,状态切换过渡时有动画就可以方便查看效果。
实例讲解VSM的使用
Demo目标:根据窗体的大小改变StackPanel子元素的堆叠方向,即Orientation值。
XAML:
<StackPanel x:Name="stackPanel"> <Rectangle Fill="Blue" Width="250" Height="250"/> <Rectangle Fill="Yellow" Width="250" Height="250"/> </StackPanel>
添加两个状态,并修改其默认名称。效果如下:
每个状态的右边都有三个操作按钮,从左到右作用依次是:
“闪电”:编辑触发状态的条件
“+”:添加状态的过渡,点击之后看到如下:
注:*代表任意状态
“-”:删除当前状态
现在来具体操作“状态”
鼠标点击“VisualStateLandscape”,则代表当前编辑的这个状态
然后在“对象和时间线”面板上选择stackPanel,在属性面板上讲Orientation值设置为Horizontal
接着编辑VisualStatePortrait状态,同上面的方法一样将Orientation值设置为Vertical
现在看看XAML的代码:
<Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="VisualStateGroup"> <VisualState x:Name="VisualStateLandscape"> <VisualState.Setters> <Setter Target="stackPanel.(StackPanel.Orientation)" Value="Horizontal"/> </VisualState.Setters> </VisualState> <VisualState x:Name="VisualStatePortrait"> <VisualState.Setters> <Setter Target="stackPanel.(StackPanel.Orientation)" Value="Vertical"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <StackPanel x:Name="stackPanel"> <Rectangle Fill="Blue" Width="250" Height="250"/> <Rectangle Fill="Yellow" Width="250" Height="250"/> </StackPanel> </Grid>代码并不复杂,多出来的那些其实就是刚刚的操作产生的,如果你喜欢手动敲XAML当然也可以手写
现在添加触发条件Trigger
添加简单的几行,修改后的VisualStateGroup:
<VisualStateGroup x:Name="VisualStateGroup"> <VisualState x:Name="VisualStateLandscape"> <VisualState.Setters> <Setter Target="stackPanel.(StackPanel.Orientation)" Value="Horizontal"/> </VisualState.Setters> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="501"/> </VisualState.StateTriggers> </VisualState> <VisualState x:Name="VisualStatePortrait"> <VisualState.Setters> <Setter Target="stackPanel.(StackPanel.Orientation)" Value="Vertical"/> </VisualState.Setters> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0"/> </VisualState.StateTriggers> </VisualState> </VisualStateGroup>其实就是添加了两段:
<VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth=".."/> </VisualState.StateTriggers>
运行应用,通过改变窗体的宽度,就可以看到效果了
窗体宽大于500时:
窗体宽小于500时:
除了根据窗体的宽或高触发状态,还可以自定义Trigger类(Custom triggers),要继承自StateTriggerBase类
OrientationTrigger类根据窗体的横向或纵向来触发状态:
class OrientationTrigger:StateTriggerBase { public OrientationTrigger() { Window.Current.SizeChanged += (s, e) => { SetActive(ApplicationView.GetForCurrentView().Orientation.Equals(this.Orientation)); }; SetActive(ApplicationView.GetForCurrentView().Orientation.Equals(this.Orientation)); } public ApplicationViewOrientation Orientation { get; set; } }
<VisualState.StateTriggers> <t:OrientationTrigger Orientation="Landscape"/> </VisualState.StateTriggers>
<VisualState.StateTriggers> <t:OrientationTrigger Orientation="Portrait"/> </VisualState.StateTriggers>
xmlns:t="using:App1.Triggers"
State状态可以做的修改有很多,包括控件的字体、颜色、布局、大小等等,都可以在Blend中实现
i