zoukankan      html  css  js  c++  java
  • WP7应用开发笔记技巧 使用VisualState布置屏幕方向处理

    VisualState是什么?

    VisualState 指定控件处于特定状态时的外观。

    例如,按下 Button 时,它的边框颜色可能与正常时的颜色不同。VisualState 类具有更改控件外观的 Storyboard 属性。控件进入 VisualState.Name 属性指定的状态时,Storyboard 开始。控件退出该状态时,Storyboard 停止。

    例如CheckBox就有下面几种状态组:


    使用 VisualStateManager 通过将 VisualState 对象的名称传递到 GoToState 方法,来进行状态过渡。

    深入学习:

    谈谈Silverlight 2中的视觉状态管理

    http://kb.cnblogs.com/page/42918/

    VisualState 类
    http://msdn.microsoft.com/zh-cn/library/system.windows.visualstate(VS.95).aspx

    WP的屏幕方向处理

    简单说一下WP屏幕方向一共主要有3种 竖向Portrait、左横向LandscapeLeft、右横向LandscapeRight,不支持倒置。

    屏幕方向和PhoneApplicationPage相关,可以对每一个页面单独设置。

    相关的属性和事件有:

    SupportedOrientations  获取或设置页面所支持的手机方向,只能横、只能竖、横竖都可以。

    Orientation 获取当前页面的方向

    OrientationChanged 页面方向改变时触发此事件

    因为竖向分辨率为480*800,横向分辨率为800*480,在布局和呈现上有很大的区别:

    可以参考一下这篇文章:

    http://www.cnblogs.com/mcgrady/archive/2012/02/06/2340598.html

    使用VisualState布置屏幕方向处理

    前面说了这么多,现在进入正题,既然VisualState 指定控件处于特定状态时的外观,而PhoneApplicationPage在方向上又有至少2种状态,那么可以使用VisualState 来呈现竖向Portrait和横向Landscape的两种状态。

    来演练一个例子: 在竖向的时候显示圆形,在横向的时候显示方形。

     

    先在界面上添加一个圆形和方形,默认方向是竖向,方形不可见,所以的Opacity为0。

    <!--ContentPanel - 在此放置附加内容--> 
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <Rectangle x:Name="rectangle" Fill="#FFF4F4F5" Height="96" Margin="125,146,177,0" Opacity="0" Stroke="Black" VerticalAlignment="Top"/>
    <Ellipse x:Name="ellipse" Fill="#FFF4F4F5" Height="158" Margin="117,110,138,0" Opacity="1" Stroke="Black" VerticalAlignment="Top"/>
    </Grid>



    首先是自定义VisualState

    我将状态定义到名字LayoutRoot的Grid 上,也就是默认的那个Grid 。

    定义VisualStateGroup 为Layout ,再添加2个VisualState 分别叫竖向Portrait和横向Landscape

    <Grid x:Name="LayoutRoot" Background="Transparent"> 
    <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="Layout">
    <VisualState x:Name="Portrait"></VisualState>
    <VisualState x:Name="Landscape"></VisualState>
    </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>



    然后为VisualState添加动画版Storyboard

    在竖向Portrait状态圆形可见,将Opacity设置为1,将方形Opacity设置为0。

    <VisualState x:Name="Portrait"> 
    <Storyboard>
    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ellipse" d:IsOptimized="True"/>
    <DoubleAnimation Duration="1" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
    </Storyboard>
    </VisualState>



    在横向Landscape状态方形可见,将Opacity设置为1,将圆形形Opacity设置为0。

                    <VisualState x:Name="Landscape"> 
    <Storyboard>
    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
    <DoubleAnimation Duration="1" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ellipse" d:IsOptimized="True"/>
    </Storyboard>
    </VisualState>

    还可以添加Transitions实现动画过度:

    <VisualStateGroup.Transitions> 
    <VisualTransition GeneratedDuration="0:0:1" To="Portrait"/>
    <VisualTransition GeneratedDuration="0:0:1" To="Landscape"/>
    </VisualStateGroup.Transitions>

    完整页面代码如下,当然使用Blend编辑起来更方便:

    View Code
    <phone:PhoneApplicationPage
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone
    ="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell
    ="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable
    ="d" d:DesignWidth="480" d:DesignHeight="768"
    x:Class
    ="WindowsPhoneApplication2.MainPage"
    FontFamily
    ="{StaticResource PhoneFontFamilyNormal}"
    FontSize
    ="{StaticResource PhoneFontSizeNormal}"
    Foreground
    ="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations
    ="PortraitOrLandscape" Orientation="Portrait"
    shell:SystemTray.IsVisible
    ="True" OrientationChanged="PhoneApplicationPage_OrientationChanged">

    <!--LayoutRoot 是放置所有页面内容的根网格-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
    <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="Layout">
    <VisualStateGroup.Transitions>
    <VisualTransition GeneratedDuration="0:0:1" To="Portrait"/>
    <VisualTransition GeneratedDuration="0:0:1" To="Landscape"/>
    </VisualStateGroup.Transitions>
    <VisualState x:Name="Portrait">
    <Storyboard>
    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ellipse" d:IsOptimized="True"/>
    <DoubleAnimation Duration="1" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
    </Storyboard>
    </VisualState>
    <VisualState x:Name="Landscape">
    <Storyboard>
    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
    <DoubleAnimation Duration="1" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ellipse" d:IsOptimized="True"/>
    </Storyboard>
    </VisualState>
    </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--TitlePanel 包含应用程序名称和页面标题-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
    <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
    <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <!--ContentPanel - 在此放置附加内容-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <Rectangle x:Name="rectangle" Fill="#FFF4F4F5" Height="96" Margin="125,146,177,0" Opacity="0" Stroke="Black" VerticalAlignment="Top"/>
    <Ellipse x:Name="ellipse" Fill="#FFF4F4F5" Height="158" Margin="117,110,138,0" Opacity="1" Stroke="Black" VerticalAlignment="Top"/>
    </Grid>
    </Grid>
    </phone:PhoneApplicationPage>

    使用OrientationChanged 事件切换VisualState

    首先是监听事件OrientationChanged="PhoneApplicationPage_OrientationChanged"。

    然后使用 VisualStateManager 通过将 VisualState 对象的名称传递到 GoToState 方法,来进行状态过渡。

    代码如下:

    private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) 
    {
    switch (e.Orientation)
    {
    case PageOrientation.Landscape:
    case PageOrientation.LandscapeLeft:
    case PageOrientation.LandscapeRight:
    VisualStateManager.GoToState(this, "Landscape", true);
    break;
    default:
    VisualStateManager.GoToState(this, "Portrait", true);
    break;
    }

    }

    测试效果:

    使用模拟器旁边的按钮可以很容易的测试效果:

     这样利用VisualState就可以实现比较复杂的方向变化的布局、过度动画等。

    并且利用Blend4可以使用可视化编辑也很方便。

    /h3

  • 相关阅读:
    Elastic-Job分布式任务调度
    java.sql.BatchUpdateException: ORA-01861: 文字与格式字符串不匹配
    oracle锁表和解锁
    sql ibatis
    唯一索引
    斐波那契数列
    旋转数组的最小数字
    两个栈来实现一个队列
    重建二叉树
    重写和重载
  • 原文地址:https://www.cnblogs.com/kiminozo/p/2347903.html
Copyright © 2011-2022 走看看