为了账号安全,请及时绑定邮箱和手机立即绑定

UWP 连接动画在第二次使用后崩溃

UWP 连接动画在第二次使用后崩溃

C#
潇湘沐 2021-07-05 17:59:38
我已经用一个点击事件连接了两个表单,该事件在两个方向上触发了一个连接的动画。第一次前进和后退它工作正常。第二次前进它可以工作,但尝试第二次返回会导致应用程序崩溃并出现以下异常:System.ArgumentException: 参数不正确。无法启动动画 - 源元素不在元素树中。这发生在 SecondPage_BackRequested 的第一行,但仅在第二次执行时发生。第一次执行工作和动画完美。任何帮助将不胜感激。我已经翻阅了相关的动画文档,据我所知,这是应该如何使用它的,但是我找不到任何地方发生的此错误的参考。我的代码(MainPageViewModel 被省略,因为它不相关,但可以根据要求添加):主页.xaml<Page    x:Class="AnimTest.Views.Main.MainPage"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    xmlns:models="using:AnimTest.Models"    xmlns:main="using:AnimTest.Views.Main"    mc:Ignorable="d">    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"          Padding="10">        <Grid.RowDefinitions>            <RowDefinition Height="Auto"/>            <RowDefinition Height="*"/>        </Grid.RowDefinitions>        <TextBlock Grid.Row="0"                   Style="{ThemeResource HeaderTextBlockStyle}"                   Text="AnimTest"/>        <GridView x:Name="TileGrid"                  Grid.Row="1"                  IsItemClickEnabled="True"                  ItemsSource="{x:Bind ViewModel.Tiles, Mode=OneWay}"                  ItemClick="GridView_ItemClick"                  Loaded="TileGrid_Loaded">            <GridView.ItemTemplate>                <DataTemplate x:DataType="models:Tile">                    <Border x:Name="TileBorder"                            Background="Red"                            MinHeight="150"                            MinWidth="200">
查看完整描述

1 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

问题实际上不在于连接的动画,而在于导航事件。


第一次到达时,SecondPage您连接了BackRequested活动,当您返回时,一切都很好。然而,事件处理程序停留配属到事件即使您在导航SecondPage。这是一个问题,因为一旦你SecondPage再次导航到,现在偶数将被注册两次。并且处理程序第一次运行时失败,因为第一个处理程序连接到页面的前一个实例,并且连接的动画已经完成了这个。最后 - 由于事件,页面将永远留在内存中,这可能会导致严重的内存泄漏。


解决方案非常简单 - 您必须确保在离开页面时不要忘记取消订阅偶数处理程序,例如在OnNavigatedFrom方法中并在OnNavigatedTo方法中订阅以获得更好的清晰度:


public sealed partial class SecondPage : Page

{

    public SecondPage()

    {

        this.InitializeComponent();


    }


    protected override void OnNavigatedFrom(NavigationEventArgs e)

    {

        base.OnNavigatedFrom(e);

        SystemNavigationManager.GetForCurrentView().BackRequested -= SecondPage_BackRequested;

    }


    private void SecondPage_BackRequested(object sender, BackRequestedEventArgs e)

    {

        ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("borderOut", MainBorder);

        Frame?.GoBack();

        e.Handled = true;

    }


    protected override void OnNavigatedTo(NavigationEventArgs e)

    {

        base.OnNavigatedTo(e);

        SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;

        SystemNavigationManager.GetForCurrentView().BackRequested += SecondPage_BackRequested;


        var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("borderIn");

        animation?.TryStart(MainBorder);

    }

}

为了避免这种问题,我通常在BackRequested中为整个应用程序设置事件,App并在启动时只订阅一次。然后,您可以将连接的动画代码放入OnNavigatedFrom方法中,而不必订阅BackRequested:


protected override void OnNavigatedFrom(NavigationEventArgs e)

{

    base.OnNavigatedFrom(e);       

    ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("borderOut", MainBorder);

}


查看完整回答
反对 回复 2021-07-10
  • 1 回答
  • 0 关注
  • 174 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信