user2950509
user2950509

Reputation: 1057

Composition animation in a custom Page control?

i've created a custom control that inherits from Page, to animate the NavigatingFrom event. However, I don't seem to be able to play the actual animation. This is my full AltPage.cs code:

public class AltPage : Page
{
    protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
    {
        //Set up the composition animation
        var _compositor = new Compositor();
        var _targetVisual = ElementCompositionPreview.GetElementVisual(this);
        var animation = _compositor.CreateScalarKeyFrameAnimation();
        animation.Duration = new TimeSpan(0, 0, 0, 0, 300);
        animation.InsertKeyFrame(1.0f, 0f);


        _targetVisual.StartAnimation("Opacity", animation);

        //Give some time for the animation to start
        Task.Delay(18);

        //Get the page to initialize while the animation is playing
        base.OnNavigatingFrom(e);
    }
}

When I run the code, the line _targetVisual.StartAnimation("Opacity", animation) lifts a System.UnauthorizedAccessException. i'm told that "The caller is not allowed to perform this operation on this object". What am I doing wrong?

Upvotes: 3

Views: 244

Answers (1)

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10831

When I run the code, the line _targetVisual.StartAnimation("Opacity", animation) lifts a System.UnauthorizedAccessException. i'm told that "The caller is not allowed to perform this operation on this object".

The Compositor object needs to be got from any Visual of current Page. You can use the following codes to got a Compositor:

ElementCompositionPreview _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

Page.OnNavigatingFrom was raised before Navigation, but we can't give a delay to prevent the page from navigating. When we are using Task.Delay, we need an await to let it work synchronously. But it will make the whole function runs asychronously(async will be added when using await). So,if you put your codes in OnNavigatingFrom, you won't get the expected behavior.

As a workaround, you can put your codes before Frame.Navigate like below:

Compositor _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
Visual _targetVisual = ElementCompositionPreview.GetElementVisual(this);
var animation = _compositor.CreateScalarKeyFrameAnimation();
animation.Duration = new TimeSpan(0, 0, 0, 0, 3000);
animation.InsertKeyFrame(0.0f, 1.0f);
animation.InsertKeyFrame(1.0f, 0.0f);

_targetVisual.StartAnimation("Opacity", animation);
await Task.Delay(3000);//Give some time for the animation to start
Frame.Navigate(typeof(NewPage));

Thus, you will get an animation of page fading, and I have made a demo, that you can refer to:CustomPageSample.

Upvotes: 1

Related Questions