zoukankan      html  css  js  c++  java
  • SilverLight之路(十三)

    经过前面一十二回的介绍,我们这个项目已经有了一些效果,但至今还没有一点动画元素,上一节最后,我想尝试一下动画效果,结果还失败了。不过也正是以此为契机,使我在动画方面有了一些实践,这一节我们试着做一些动画效果出来。

    比如当点击基金名称后,以一个翻转效果切换到基金详情页面

     

     

    呵呵,虽然比较丑,但我们关注的是实现,毕竟不是美工嘛。

    按照我们一贯的风格,不去介绍长篇大论的理论与基础,我们还是以动手实践为主。

    提到动画,自然就会想到Storyboard,没错,它是一切动画的基础,除非你自己写计时器去自己控制。那我们就先建一个Storyboard!在哪建呢?我们的动画过渡是要在行情与详情页面间做切换,自然动画就要建立在它们的父级,也就是“基金行情”项目的MainPage中了。(再强调一下,我们是以学习为主,并不是在做项目,因此我们这里没有用什么模式,只以简单实现为主)

    看一下动画的实现原理,应该很自然就可以想到,用一个动画控制一个容器旋转,转到垂直角度后,把容器中的控件换成目标控件,再把容器用另一个动画还原回原来的状态。这里为什么要用两个动画来实现,是因为我们可以在第一个动画的结束事件里来做切换控件的动作,而除了Completed事件外,我还真没找到还有其它事件。

     

    回顾一下我们的MainPage结构

     

     

    SVMain就是我们的容器,它是一个ScrollViewer,因为不同的功能页面大小是不同的,所以使用ScrollViewer做为容器可以解决滚动问题,那么我们的动画就是设置它翻转就可以了。第一个动画Storyboard_GoToDetails

     

    我们在0秒与1秒的位置插入关键帧,并设置1秒处的SVMain的旋转角度为-90度,如

     

    接下来创建第二个动画Storyboard_GoToDetails_Second

    效果与第一个相反,即在第0秒的位置,设置SVMain的旋转角度为-90度,在第1秒的位置还原

    动画的代码全由Blend自动生成,如下

     

    View Code
    <UserControl.Resources>

    <Storyboard x:Name="Storyboard_GoToDetails">

    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="SVMain">

    <EasingDoubleKeyFrame KeyTime="0" Value="0"/>

    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>

    </DoubleAnimationUsingKeyFrames>

    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="SVMain">

    <EasingDoubleKeyFrame KeyTime="0" Value="0"/>

    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-90"/>

    </DoubleAnimationUsingKeyFrames>

    </Storyboard>

    <Storyboard x:Name="Storyboard_GoToDetails_Second">

    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="SVMain">

    <EasingDoubleKeyFrame KeyTime="0" Value="90"/>

    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>

    </DoubleAnimationUsingKeyFrames>

    </Storyboard>

    </UserControl.Resources>

    然后我们在第一个动画的Complete事件中切换控件,并开始第二个动画,如

     

    void Storyboard_GoToDetails_Completed(object sender, EventArgs e)
    {
    FundDetails fd
    = new FundDetails();
    SVMain.Content
    =fd;
    this.Storyboard_GoToDetails_Second.Begin();
    }

    然后我们在行情控件里点击基金名称时通过委托或MainPage的引用启动第一个动画,我们的效果就实现了,很简单吧!

     

    再看看我们第二个动画的效果,即在详情页面时通过点击导航上的行情按钮返回基金行情页面,如

     

    一个类似3D翻转的效果,这个效果我们分析一下,其实也不很难,主要是控制好角度与位置,但显然的,一个容器满足不了要求了,因为我们会有两个控件同时存在的情况。那我们就要修改一下MainPage中的布局,如

     

    具体实现的效果,网上有网友发布了一个封装好的类cShow3DPlane,可以拿来直接用,调用代码如

     

    private cShow3DPlane c3d = new cShow3DPlane();



    if (c3d.MoveOver())

    {

    c3d.SetInOutPlane(
    this.gridS1, this.gridS2, enumDirection.Right);

    c3d.Begin();

    }

    这块有一点要注意一下,默认情况下,当一个动画结束后,它会保留它最终的状态,因此,当我们做切换的时候,要注意两个grid的状态,在我们这个实现中,为了保留第一个动作的效果(因为两个动画是不同的实现,第一个动画是用同一个容器实现的),我需要记录下当前是哪一个grid正在被显示,而且如果当前已经是在行情界面的话,再点击行情导航按钮应该就不需要再有动作了,最终代码如下

     

    View Code
    private Grid currentGrid;//当前控件窗口,用以动画切换

    private void LoadFundQuotes(Grid grids)
    {
    //加载基金行情

    FundQuotes fq
    = new FundQuotes();

    fq.mp
    = this;

    grids.Children.Clear();

    grids.Children.Add(fq);

    }



    private void HyperlinkButton_Click(object sender, System.Windows.RoutedEventArgs e)

    {

    if (currentGrid.Children.Count > 0 && currentGrid.Children[0] as FundQuotes == null)

    {
    //如果当前显示模块不是基金行情

    if (currentGrid == this.gridS1)

    {

    LoadFundQuotes(
    this.gridS2);

    if (c3d.MoveOver())

    {

    c3d.SetInOutPlane(
    this.gridS2, this.gridS1, enumDirection.Right);

    c3d.Begin();

    currentGrid
    = this.gridS2;

    }

    }

    else if (currentGrid == this.gridS2)

    {

    LoadFundQuotes(
    this.gridS1);

    if (c3d.MoveOver())

    {

    c3d.SetInOutPlane(
    this.gridS1, this.gridS2, enumDirection.Right);

    c3d.Begin();

    currentGrid
    = this.gridS1;

    }

    }

    }

    }

    因为布局发生了变化,因此第一个动画的实现也要做相应的修改,最终代码如

     

    void Storyboard_GoToDetails_Completed(object sender, EventArgs e)

    {

    FundDetails fd
    = new FundDetails();

    fd.currentFund
    = this.gridS1.Tag as WcfService.FundQuotes;

    currentGrid.Children.Clear();

    currentGrid.Children.Add(fd);

    this.Storyboard_GoToDetails_Second.Begin();

    }

    fd.currentFund = this.gridS1.Tag as WcfService.FundQuotes;这一句我是用来向详情界面传参用的,与动画本身无关。

  • 相关阅读:
    ZROI2018提高day9t1
    p2114 起床困难综合症
    EZOJ #78
    Linux JDK配置
    jps命令
    虚拟机 网卡模式配置
    redhat下yum命令安装(替换为centos yum命令)
    URL编码
    Query DSL(2)----Full text queries
    Query DSL(1)
  • 原文地址:https://www.cnblogs.com/meteortent/p/2088175.html
Copyright © 2011-2022 走看看