From fb9e75c6e4a31135c573474c4c319d2734bb7ebd Mon Sep 17 00:00:00 2001 From: Yimeng Wu Date: Mon, 20 Apr 2020 01:59:09 +0800 Subject: [PATCH] Make SplitView transitions smoother --- ModernWpf.Controls/SplitView/SplitView.cs | 1 + .../HamburgerMenu/HamburgerMenuEx.cs | 11 +---- ModernWpf/Helpers/AnimationHelper.cs | 47 +++++++++++++++++++ ModernWpf/Properties/AssemblyInfo.cs | 1 + 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 ModernWpf/Helpers/AnimationHelper.cs diff --git a/ModernWpf.Controls/SplitView/SplitView.cs b/ModernWpf.Controls/SplitView/SplitView.cs index f9c75a74..5c38d138 100644 --- a/ModernWpf.Controls/SplitView/SplitView.cs +++ b/ModernWpf.Controls/SplitView/SplitView.cs @@ -58,6 +58,7 @@ public override void OnApplyTemplate() { _displayModeStates.CurrentStateChanging += OnDisplayModeStatesCurrentStateChanging; _displayModeStates.CurrentStateChanged += OnDisplayModeStatesCurrentStateChanged; + AnimationHelper.DeferTransitions(_displayModeStates); } UpdateTemplateSettings(); diff --git a/ModernWpf.MahApps/HamburgerMenu/HamburgerMenuEx.cs b/ModernWpf.MahApps/HamburgerMenu/HamburgerMenuEx.cs index d941e186..50b309bd 100644 --- a/ModernWpf.MahApps/HamburgerMenu/HamburgerMenuEx.cs +++ b/ModernWpf.MahApps/HamburgerMenu/HamburgerMenuEx.cs @@ -11,7 +11,6 @@ using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; -using System.Windows.Threading; using SplitView = MahApps.Metro.Controls.SplitView; using SplitViewDisplayMode = MahApps.Metro.Controls.SplitViewDisplayMode; @@ -788,16 +787,8 @@ private void PlayIndicatorAnimations(UIElement indicator, double from, double to var indicatorAsFE = (FrameworkElement)indicator; SetElementAnimation(indicatorAsFE, storyboard); + AnimationHelper.DeferBegin(storyboard); storyboard.Begin(indicatorAsFE, true); - storyboard.Pause(indicatorAsFE); - Dispatcher.BeginInvoke(() => - { - var animation = GetElementAnimation(indicatorAsFE); - if (animation == storyboard) - { - animation.Resume(indicatorAsFE); - } - }, DispatcherPriority.Render); } private void OnAnimationComplete() diff --git a/ModernWpf/Helpers/AnimationHelper.cs b/ModernWpf/Helpers/AnimationHelper.cs new file mode 100644 index 00000000..a6e0d261 --- /dev/null +++ b/ModernWpf/Helpers/AnimationHelper.cs @@ -0,0 +1,47 @@ +using System; +using System.Diagnostics; +using System.Windows; +using System.Windows.Media.Animation; +using System.Windows.Threading; + +namespace ModernWpf +{ + internal static class AnimationHelper + { + public static void DeferBegin(Storyboard storyboard) + { + storyboard.CurrentStateInvalidated += OnStoryboardCurrentStateInvalidated; + + static void OnStoryboardCurrentStateInvalidated(object sender, EventArgs e) + { + if (sender is ClockGroup clock && + clock.HasControllableRoot && + clock.CurrentState == ClockState.Active && + !clock.IsPaused) + { + clock.Controller.Pause(); + clock.Dispatcher.BeginInvoke(() => + { + Debug.Assert(clock.IsPaused || clock.CurrentState != ClockState.Active); + if (clock.IsPaused) + { + clock.Controller.Resume(); + } + }, DispatcherPriority.Loaded); + } + } + } + + public static void DeferTransitions(VisualStateGroup group) + { + foreach (VisualTransition transition in group.Transitions) + { + var storyboard = transition.Storyboard; + if (storyboard != null) + { + DeferBegin(storyboard); + } + } + } + } +} diff --git a/ModernWpf/Properties/AssemblyInfo.cs b/ModernWpf/Properties/AssemblyInfo.cs index 1c63404d..efcb596b 100644 --- a/ModernWpf/Properties/AssemblyInfo.cs +++ b/ModernWpf/Properties/AssemblyInfo.cs @@ -12,6 +12,7 @@ )] [assembly: InternalsVisibleTo("ModernWpf.Controls")] +[assembly: InternalsVisibleTo("ModernWpf.MahApps")] [assembly: XmlnsPrefix("http://schemas.modernwpf.com/2019", "ui")] [assembly: XmlnsDefinition("http://schemas.modernwpf.com/2019", "ModernWpf")]