From 849d4995393cb6ca5be4a501a5da7dadc216eb74 Mon Sep 17 00:00:00 2001 From: daniel Date: Fri, 9 Jun 2023 08:13:35 +0300 Subject: [PATCH] Use two presenter --- .../TransitioningContentControl.cs | 81 ++++++++++++++----- .../Controls/TransitioningContentControl.xaml | 3 +- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/Avalonia.Controls/TransitioningContentControl.cs b/src/Avalonia.Controls/TransitioningContentControl.cs index 21b9c9b765..bf540698f1 100644 --- a/src/Avalonia.Controls/TransitioningContentControl.cs +++ b/src/Avalonia.Controls/TransitioningContentControl.cs @@ -15,8 +15,9 @@ namespace Avalonia.Controls; public class TransitioningContentControl : ContentControl { private CancellationTokenSource? _currentTransition; - private ContentPresenter? _transitionPresenter; - private Optional _transitionFrom; + private ContentPresenter? _presenter2; + private bool _isFirstFull; + private bool _shouldAnimate; /// /// Defines the property. @@ -39,46 +40,52 @@ public class TransitioningContentControl : ContentControl { var result = base.ArrangeOverride(finalSize); - if (_transitionFrom.HasValue) + if (_shouldAnimate) { _currentTransition?.Cancel(); - if (_transitionPresenter is not null && + if (_presenter2 is not null && Presenter is Visual presenter && - PageTransition is { } transition && - (_transitionFrom.Value is not Visual v || v.VisualParent is null)) - { - _transitionPresenter.Content = _transitionFrom.Value; - _transitionPresenter.IsVisible = true; - _transitionFrom = Optional.Empty; + PageTransition is { } transition) + { + _shouldAnimate = false; var cancel = new CancellationTokenSource(); _currentTransition = cancel; - transition.Start(_transitionPresenter, presenter, true, cancel.Token).ContinueWith(x => + var from = _isFirstFull ? _presenter2 : presenter; + var to = _isFirstFull ? presenter : _presenter2; + + transition.Start(from, to, true, cancel.Token).ContinueWith(x => { if (!cancel.IsCancellationRequested) { - _transitionPresenter.Content = null; - _transitionPresenter.IsVisible = false; + HideOldPresenter(); } }, TaskScheduler.FromCurrentSynchronizationContext()); } - _transitionFrom = Optional.Empty; + _shouldAnimate = false; } return result; } + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + UpdateContent(false); + } + protected override bool RegisterContentPresenter(ContentPresenter presenter) { if (!base.RegisterContentPresenter(presenter) && presenter is ContentPresenter p && - p.Name == "PART_TransitionContentPresenter") + p.Name == "PART_ContentPresenter2") { - _transitionPresenter = p; - _transitionPresenter.IsVisible = false; + _presenter2 = p; + _presenter2.IsVisible = false; + UpdateContent(false); return true; } @@ -89,14 +96,44 @@ public class TransitioningContentControl : ContentControl { base.OnPropertyChanged(change); - if (change.Property == ContentProperty && - _transitionPresenter is not null && - Presenter is Visual && - PageTransition is not null) + if (change.Property == ContentProperty) { - _transitionFrom = change.GetOldValue(); + UpdateContent(true); + } + } + + private void UpdateContent(bool withTransition) + { + if (VisualRoot is null || _presenter2 is null || Presenter is null) + { + return; + } + + var currentPresenter = _isFirstFull ? _presenter2 : Presenter; + currentPresenter.Content = Content; + currentPresenter.IsVisible = true; + + _isFirstFull = !_isFirstFull; + + if (PageTransition is not null && withTransition) + { + _shouldAnimate = true; InvalidateArrange(); } + else + { + HideOldPresenter(); + } + } + + private void HideOldPresenter() + { + var oldPresenter = _isFirstFull ? _presenter2 : Presenter; + if (oldPresenter is not null) + { + oldPresenter.Content = null; + oldPresenter.IsVisible = false; + } } private class ImmutableCrossFade : IPageTransition diff --git a/src/Avalonia.Themes.Fluent/Controls/TransitioningContentControl.xaml b/src/Avalonia.Themes.Fluent/Controls/TransitioningContentControl.xaml index 2078322318..03cb09e395 100644 --- a/src/Avalonia.Themes.Fluent/Controls/TransitioningContentControl.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/TransitioningContentControl.xaml @@ -11,11 +11,10 @@ BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" ContentTemplate="{TemplateBinding ContentTemplate}" - Content="{TemplateBinding Content}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" /> -