Win10开发:视觉状态VisualState与自适应UI

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>

在状态面板中添加一个状态组,默认名字叫VisualStateGroup,添加状态组之后又会有两个按钮,一个是加号代表"添加状态"(在当前状态组中添加),另一个是删除状态组。

添加两个状态,并修改其默认名称。效果如下:


每个状态的右边都有三个操作按钮,从左到右作用依次是:

“闪电”:编辑触发状态的条件

“+”:添加状态的过渡,点击之后看到如下:


注:*代表任意状态

“-”:删除当前状态


现在来具体操作“状态”

鼠标点击“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>

MinWindowWidth代表触发的最小窗体宽度,也可以用MinWindowHeight(最小窗体高度)

运行应用,通过改变窗体的宽度,就可以看到效果了

 窗体宽大于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>

此处t是个命名空间的引用

xmlns:t="using:App1.Triggers"

将应用部署到手机上,当横竖屏切换时就能看到效果了


State状态可以做的修改有很多,包括控件的字体、颜色、布局、大小等等,都可以在Blend中实现

i


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值