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;这一句我是用来向详情界面传参用的,与动画本身无关。

  • 相关阅读:
    BF算法和KMP算法
    Python课程笔记 (五)
    0268. Missing Number (E)
    0009. Palindrome Number (E)
    0008. String to Integer (atoi) (M)
    0213. House Robber II (M)
    0198. House Robber (E)
    0187. Repeated DNA Sequences (M)
    0007. Reverse Integer (E)
    0006. ZigZag Conversion (M)
  • 原文地址:https://www.cnblogs.com/meteortent/p/2088175.html
Copyright © 2011-2022 走看看