#uwp #composition #winui
#uwp #композиция #winui
Вопрос:
Я считаю, что инструменты Windows.UI.Composition конфликтуют с визуальными состояниями XAML на кнопках.
GIF # 1 Когда кнопка находится в обычном состоянии, без наведения курсора, анимация работает, и кнопки успешно исчезают при прокрутке вниз, а затем снова успешно появляются при прокрутке вверх.
GIF # 2 Если курсор наведен на кнопку, когда анимация композиции завершается, и мышь выходит из кнопки перед прокруткой вверх, я полагаю, что состояние наведения указателя зависает, а непрозрачность 0% застревает. Единственный способ исправить это — снова навести курсор мыши, чтобы отменить отображение визуальных состояний XAML.
Все кнопки находятся в одной и той же панели стека, которая является целью анимации непрозрачности. Когда у одной кнопки возникает эта проблема, вся панель стека застревает с непрозрачностью 0%. Приведенный ниже код представляет собой общую суть, некоторые фрагменты опущены для краткости. Я не думаю, что это проблема с кодом, я думаю, что это ограничение платформы, и я ищу обходной путь.
CompositionPropertySet _scrollerPropertySet =
ElementCompositionPreview.GetScrollViewerManipulationPropertySet((ScrollViewer)sender);
Compositor _compositor = _scrollerPropertySet.Compositor;
CompositionPropertySet _props = _compositor.CreatePropertySet();
_props.InsertScalar("progress", 0);
var scrollingProperties =
_scrollerPropertySet.GetSpecializedReference<ManipulationPropertySetReferenceNode>();
var props = _props.GetReference();
var progressNode = props.GetScalarProperty("progress");
ExpressionNode progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1);
_props.StartAnimation("progress", progressAnimation);
// StackPanel relevant code:
Visual carOperationButtonStackPanelVisual=
ElementCompositionPreview.GetElementVisual(CarOperationStackPanel);
ExpressionNode carSubtitleObjectOpacityAnimation = 1 - (progressNode * 2);
carOperationButtonStackPanelVisual.StartAnimation("Opacity", carSubtitleObjectOpacityAnimation);
Ответ №1:
В приведенном выше фрагменте кода, ближе к концу, эта строка
ExpressionNode carSubtitleObjectOpacityAnimation = 1 - (progressNode * 2);
должно быть
ExpressionNode carSubtitleObjectOpacityAnimation = ExpressionFunctions.Lerp(0, 1, 1 - (progressNode * 2));
Это заставит непрозрачность обновляться с помощью линейной интерполяции от 0 до 1. Для чего это стоит, я скопировал исходный код из репозитория образцов пользовательского интерфейса Win, который не использует Lerp() для непрозрачности. Я пришел к выводу, что Lerp более обременителен для системы, но необходим, когда элементы управления имеют визуальные состояния. Пример репозитория анимирует простой текстовый блок (у которого нет визуальных состояний).