Я использую UWP и работаю с Composition API, чтобы программно перемещать элементы по экрану, и я обнаружил, что при первом запуске приложения начальный слайд для многих элементов выполняется неправильно.При дальнейшей проверке я обнаружил, что свойства Смещения ElementVisual, которые я использую для вычисления и установки начальных и конечных положений анимации, иногда подходят ко всем нулевым значениям для значений X, Y, Z в самой первой анимации.Лучше всего я могу сказать, что все анимации этого элемента с этого момента работают правильно, пока приложение продолжает работать.
Приложение, над которым я работаю, является более сложным и интересным, но я создал упрощенное тестовое приложениечтобы продемонстрировать проблему, с которой я сталкиваюсь.
Из нового пустого проекта UWP я добавляю следующие GridView и Button в корневую сетку страницы:
<GridView x:Name="TestGridView" HorizontalAlignment="Center" VerticalAlignment="Center">
<GridViewItem >
<Border Width="125" Height="125">
<Grid>
<TextBlock Text="Content String 1" />
</Grid>
</Border>
</GridViewItem>
<GridViewItem>
<Border Width="125" Height="125">
<Grid>
<TextBlock Text="Content String 2" />
</Grid>
</Border>
</GridViewItem>
<GridViewItem>
<Border Width="125" Height="125">
<Grid>
<TextBlock Text="Content String 3"/>
</Grid>
</Border>
</GridViewItem>
</GridView>
<Button Height="125" Width="125" Click="Button_Click"/>
В файле codebehind, который я добавляюследующие дополнительные операторы using, объявление переменной и этот обработчик событий:
using System.Numerics;
using Windows.UI.Composition;
using Windows.UI.Xaml.Hosting;
using System.Diagnostics;
Compositor compositor;
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (var element in TestGridView.ItemsPanelRoot.Children)
{
var slideVisual = ElementCompositionPreview.GetElementVisual(element);
Debug.WriteLine("Element Offset: " + slideVisual.Offset);
var slideAnimation = compositor.CreateVector3KeyFrameAnimation();
slideAnimation.InsertKeyFrame(0f, slideVisual.Offset);
slideAnimation.InsertKeyFrame(1f, new Vector3(slideVisual.Offset.X, slideVisual.Offset.Y + 20f, 0f));
slideAnimation.Duration = TimeSpan.FromMilliseconds(800);
slideVisual.StartAnimation(nameof(slideVisual.Offset), slideAnimation);
}
}
Я также инициализирую композитор в конструкторе MainPage ():
public MainPage()
{
this.InitializeComponent();
compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
}
Затем запускаю проект вРежим отладки из Visual Studio.Нажатие на кнопку приводит к следующему выводу в моем «Немедленном окне» (для ясности добавлены разделительные линии в редактировании)
Element Offset: <0, 0, 0>
Element Offset: <0, 0, 0>
Element Offset: <0, 0, 0>
Element Offset: <0, 20, 0>
Element Offset: <129, 0, 0>
Element Offset: <258, 0, 0>
Element Offset: <0, 40, 0>
Element Offset: <129, 20, 0>
Element Offset: <258, 20, 0>
Element Offset: <0, 60, 0>
Element Offset: <129, 40, 0>
Element Offset: <258, 40, 0>
Обратите внимание, что первый из трех элементов анимируется на первом слайде, а два других - нет.и что все их значения смещения равны нулю.
На каждом слайде после всех трех элементов анимируются с их предыдущей позиции, как и должно, хотя побочные эффекты от анимации первого слайда сохраняются.
Я безуспешно пытался найти способ заставить элементы в нашем приложении обновить их значения смещения, чтобы начальная анимация слайдов для каждого элемента работала правильно, включая такие вещи, как вставка фиктивной анимации WarmUp непосредственно перед фактической предполагаемой анимацией, которая очень быстроговорит элементу либо о перемещении из его текущей позиции в ту же позицию, либо очень немного измененную стартовую позицию в его текущую текущую позицию.
var warmUpAnimation = compositor.CreateVector3KeyFrameAnimation();
warmUpAnimation.InsertKeyFrame(0.0f, new Vector3(slideVisual.Offset.X + 1, slideVisual.Offset.Y, slideVisual.Offset.Z));
warmUpAnimation.InsertKeyFrame(1f, slideVisual.Offset);
warmUpAnimation.Duration = TimeSpan.FromMilliseconds(1);
Я предполагаю, что это ошибка в окнеs Composition API, но я надеюсь, что кто-то может предложить простой и эффективный обходной путь, который заставит ElementVisual корректно инициализироваться после загрузки.