Storyboard.Completed和OnNavigatingFrom。如何正确做动画?

时间:2013-12-19 13:26:17

标签: c# xaml animation windows-phone

我希望在用户导航到应用程序中的某个页面时进行简单的动画制作。这就是我现在所拥有的:

XAML:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.Projection>
        <PlaneProjection CenterOfRotationY="1"/>
    </Grid.Projection>
    <Grid.Resources>
        <Storyboard x:Name="OnNavTo">
            <DoubleAnimation
                Storyboard.TargetName="LayoutRoot"
                Storyboard.TargetProperty="(Projection).(PlaneProjection.RotationX)"
                From="-110" To="0" Duration="0:0:0.3" />
        </Storyboard>
        <Storyboard x:Name="OnNavFrom">
            <DoubleAnimation
                Storyboard.TargetName="LayoutRoot"
                Storyboard.TargetProperty="(Projection).(PlaneProjection.RotationX)"
                From="0" To="-110" Duration="0:0:1.3" />
        </Storyboard>
    </Grid.Resources>
    <phone:Pivot Title="{Binding LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}">
        <!-- My page stuff here -->
    </phone:Pivot>
</Grid>

C#:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    OnNavTo.Begin();
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);
    OnNavFrom.Begin();
}

OnNavigatedTo正常工作。当我点击按钮打开适当的页面时,它会打开动画。但是,当我按下后退按钮时,页面只是关闭,没有任何动画。 请指出我正确的方向

(我更喜欢后端的python开发人员,在Windows Phone和.NET中绝对是noob)。

UPD 正如gaurav5430指出的那样。

首先:我注意到,我使用OnNavigatedFrom代替OnNavigatingFrom

第二:动画是异步的,所以我需要等到它完成才真正关闭页面。在这一点上,我来到了以下:

XAML:<Storyboard x:Name="OnNavFrom" Completed="OnNavFrom_Completed">

C#:

private bool cancelExit = true;

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    e.Cancel = cancelExit;
    if (cancelExit)
    {
        OnNavFrom.Begin();
    }
    else
    {
        base.OnNavigatingFrom(e);
    }
}

private void OnNavFrom_Completed(object sender, EventArgs e)
{
    cancelExit = false;
    NavigationService.GoBack();
}

它正在运作。虽然我知道这不是处理事件的最佳方式。我非常确定C#有很好的方法可以在不调用NavigationService两次的情况下执行此操作(第一次是用户按下时,第二次是动画完成时)。 gaurav5430提供的链接包含代码示例。但我不明白它是如何工作的。我认为对于像我这样的新手来说,这段代码太小了,无法理解幕后的内容。

也可以

2 个答案:

答案 0 :(得分:1)

页面很可能已经导航,并且不会等待动画完成。

我建议在调用base.OnNavigatedFrom(e)之前调用所有函数,因为这可能是设置导航的函数,所以基本上你可以试试

   protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
     OnNavFrom.Begin();
        base.OnNavigatedFrom(e);

    }

请注意,这仍然无法确保等待动画完成,因为动画可能会播放为异步。所以也许你可以在调用base.OnNavigatedFrom()

之前尝试添加一些延迟

您也可以查看此链接

http://www.silverlightshow.net/items/Windows-Phone-7-Part-3-Understanding-navigation.aspx

答案 1 :(得分:0)

谢谢,基于此,我不得不添加一些改进。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    //base.OnNavigatedTo(e); //this call isn't necessary
    if (e.NavigationMode == NavigationMode.New)
    {
       storyboardTo.Begin();
    }
    //if NavigationMode is Back then don't play the animation

    //...
}

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    if (e.NavigationMode != NavigationMode.Back)
    {//leave the page due to long back button or Windows button, stay on the page
        e.Cancel = true;
        return;
    }

    //...
    //base.OnNavigatingFrom(e); //this call isn't necessary
    //...
}