Storyboard.Completed and OnNavigatingFrom. How to

2019-08-09 03:51发布

I want to make simple animation when user is navigated to and from some page in application. Here is what I have for now:

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 works fine. When I tap button to open appropriate page, it opens with animation. But, when I press back button, page is simply closed, without any animation. Please point me in correct direction

(I'm rather back-end python developer, and absolutely noob in Windows Phone and .NET stuff).

UPD As pointed by gaurav5430.

First: I have noticed, that I'm using OnNavigatedFrom instead of OnNavigatingFrom

Second: Animation is asynchronous, so I need to wait till it is finished before close the page actually. At this point, I came to the following:

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();
}

It's working. Though I understand it's not the best way to deal with events. I'm pretty sure C# has nice ways to do this without calling NavigationService twice (1st when user press back and 2nd when animation is complete). The link provided by gaurav5430 contains example of code. But I don't understand how it works. I think the piece of code is too small, for novice like me, to understand what is behind the scene.

So can

2条回答
等我变得足够好
2楼-- · 2019-08-09 04:11

It is quite possible that the page has been navigated from and does not wait for the animation to complete.

what i would suggest is to call all your functions before calling base.OnNavigatedFrom(e), because that is probably the function which sets up the navigation, so basically you can try

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

    }

please note that this still does not make sure that it waits for your animation to complete, as the animation would probably be played async. so maybe you could try adding some delay before calling base.OnNavigatedFrom()

also you might check this link out

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

查看更多
forever°为你锁心
3楼-- · 2019-08-09 04:31

thanks, and based on it, I had to add some improvements.

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
    //...
}
查看更多
登录 后发表回答