猿问

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

我已经用一个点击事件连接了两个表单,该事件在两个方向上触发了一个连接的动画。第一次前进和后退它工作正常。第二次前进它可以工作,但尝试第二次返回会导致应用程序崩溃并出现以下异常:


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">


潇湘沐
浏览 175回答 1
1回答

holdtom

问题实际上不在于连接的动画,而在于导航事件。第一次到达时,SecondPage您连接了BackRequested活动,当您返回时,一切都很好。然而,事件处理程序停留配属到事件即使您在导航SecondPage。这是一个问题,因为一旦你SecondPage再次导航到,现在偶数将被注册两次。并且处理程序第一次运行时失败,因为第一个处理程序连接到页面的前一个实例,并且连接的动画已经完成了这个。最后 - 由于事件,页面将永远留在内存中,这可能会导致严重的内存泄漏。解决方案非常简单 - 您必须确保在离开页面时不要忘记取消订阅偶数处理程序,例如在OnNavigatedFrom方法中并在OnNavigatedTo方法中订阅以获得更好的清晰度:public sealed partial class SecondPage : Page{&nbsp; &nbsp; public SecondPage()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; this.InitializeComponent();&nbsp; &nbsp; }&nbsp; &nbsp; protected override void OnNavigatedFrom(NavigationEventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; base.OnNavigatedFrom(e);&nbsp; &nbsp; &nbsp; &nbsp; SystemNavigationManager.GetForCurrentView().BackRequested -= SecondPage_BackRequested;&nbsp; &nbsp; }&nbsp; &nbsp; private void SecondPage_BackRequested(object sender, BackRequestedEventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("borderOut", MainBorder);&nbsp; &nbsp; &nbsp; &nbsp; Frame?.GoBack();&nbsp; &nbsp; &nbsp; &nbsp; e.Handled = true;&nbsp; &nbsp; }&nbsp; &nbsp; protected override void OnNavigatedTo(NavigationEventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; base.OnNavigatedTo(e);&nbsp; &nbsp; &nbsp; &nbsp; SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;&nbsp; &nbsp; &nbsp; &nbsp; SystemNavigationManager.GetForCurrentView().BackRequested += SecondPage_BackRequested;&nbsp; &nbsp; &nbsp; &nbsp; var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("borderIn");&nbsp; &nbsp; &nbsp; &nbsp; animation?.TryStart(MainBorder);&nbsp; &nbsp; }}为了避免这种问题,我通常在BackRequested中为整个应用程序设置事件,App并在启动时只订阅一次。然后,您可以将连接的动画代码放入OnNavigatedFrom方法中,而不必订阅BackRequested:protected override void OnNavigatedFrom(NavigationEventArgs e){&nbsp; &nbsp; base.OnNavigatedFrom(e);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("borderOut", MainBorder);}
随时随地看视频慕课网APP
我要回答