From c65c0b18e8e37b689566b68eb4508ae88956559f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 15 Mar 2021 14:16:52 +0100 Subject: [PATCH 1/6] Added notification for property changes to implicit animations Used registered callbacks to avoid the overhead in explicit animations. This way the callbacks and events are only present and used when an implicit animation is actually used, since explicit ones use a new AnimationBuilder instance every time anyway, so notification is not necessary. --- .../Xaml/Abstract/Animation.cs | 6 +-- .../ImplicitAnimation{TValue,TKeyFrame}.cs | 39 ++++++++++++++++++- .../Interfaces/IInternalImplicitAnimation.cs | 22 +++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index 210e3828d5a..40df464bd8b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -91,14 +91,14 @@ public EasingMode? EasingMode /// public RepeatOption Repeat { - get => (RepeatOption)GetValue(RepeatOptionProperty); - set => SetValue(RepeatOptionProperty, value); + get => (RepeatOption)GetValue(RepeatProperty); + set => SetValue(RepeatProperty, value); } /// /// Identifies the dependency property. /// - public static readonly DependencyProperty RepeatOptionProperty = DependencyProperty.Register( + public static readonly DependencyProperty RepeatProperty = DependencyProperty.Register( nameof(Repeat), typeof(RepeatOption), typeof(Animation), diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 3f9ffc479ec..6e5c58e9ecb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -4,6 +4,7 @@ #nullable enable +using System; using Windows.UI.Composition; using Windows.UI.Xaml; using static Microsoft.Toolkit.Uwp.UI.Animations.AnimationExtensions; @@ -14,9 +15,35 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// A base model representing a typed animation that can be used as an implicit composition animation. /// /// - public abstract class ImplicitAnimation : Animation, IImplicitTimeline + public abstract class ImplicitAnimation : Animation, IImplicitTimeline, IInternalImplicitAnimation where TKeyFrame : unmanaged { + /// + private event EventHandler? AnimationPropertyChanged; + + /// + /// Initializes a new instance of the class. + /// + protected ImplicitAnimation() + { + RegisterPropertyChangedCallback(DelayProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(DurationProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(EasingTypeProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(EasingModeProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(RepeatProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(DelayBehaviorProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(ToProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(FromProperty, RaiseAnimationPropertyChanged); + RegisterPropertyChangedCallback(KeyFramesProperty, RaiseAnimationPropertyChanged); + } + + /// + event EventHandler? IInternalImplicitAnimation.AnimationPropertyChanged + { + add => AnimationPropertyChanged += value; + remove => AnimationPropertyChanged -= value; + } + /// /// Gets or sets the optional implicit target for the animation. This can act as a trigger property for the animation. /// @@ -67,5 +94,15 @@ public CompositionAnimation GetAnimation(UIElement element, out string? target) return builder.GetAnimation(element.GetVisual(), out _); } + + /// + /// Raises event. + /// + /// The instance raising the event. + /// The that was changed. + private void RaiseAnimationPropertyChanged(DependencyObject sender, DependencyProperty property) + { + AnimationPropertyChanged?.Invoke(this, EventArgs.Empty); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs new file mode 100644 index 00000000000..e83a427ff3c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An interface adding notification support to implicit animations. This is needed to + /// avoid the type parameters when the event is subscribed to from . + /// + internal interface IInternalImplicitAnimation + { + /// + /// Raised whenever a property that influences the animation changes. + /// + event EventHandler? AnimationPropertyChanged; + } +} From df21f078f3d209ce699f76ed64899c4a1d197e35 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 15 Mar 2021 14:17:06 +0100 Subject: [PATCH 2/6] Enabled notification updates to Implicit APIs --- .../Implicit.cs | 25 +++++------ .../Xaml/ImplicitAnimationSet.cs | 43 +++++++++++++++++++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs index 93c799013e8..ab2bda58beb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; @@ -130,7 +131,7 @@ public static void SetAnimations(UIElement element, ImplicitAnimationSet value) /// The instance for the current event. private static void OnShowAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - static void OnAnimationsChanged(IObservableVector sender, IVectorChangedEventArgs args) + static void OnAnimationsChanged(object sender, EventArgs e) { var collection = (ImplicitAnimationSet)sender; @@ -142,15 +143,15 @@ static void OnAnimationsChanged(IObservableVector sender, IVec if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.VectorChanged -= OnAnimationsChanged; + oldCollection.AnimationsChanged -= OnAnimationsChanged; } if (d is UIElement element && e.NewValue is ImplicitAnimationSet collection) { collection.ParentReference = new(element); - collection.VectorChanged -= OnAnimationsChanged; - collection.VectorChanged += OnAnimationsChanged; + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); @@ -164,7 +165,7 @@ static void OnAnimationsChanged(IObservableVector sender, IVec /// The instance for the current event. private static void OnHideAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - static void OnAnimationsChanged(IObservableVector sender, IVectorChangedEventArgs args) + static void OnAnimationsChanged(object sender, EventArgs e) { var collection = (ImplicitAnimationSet)sender; @@ -176,15 +177,15 @@ static void OnAnimationsChanged(IObservableVector sender, IVec if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.VectorChanged -= OnAnimationsChanged; + oldCollection.AnimationsChanged -= OnAnimationsChanged; } if (d is UIElement element && e.NewValue is ImplicitAnimationSet collection) { collection.ParentReference = new(element); - collection.VectorChanged -= OnAnimationsChanged; - collection.VectorChanged += OnAnimationsChanged; + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); @@ -198,7 +199,7 @@ static void OnAnimationsChanged(IObservableVector sender, IVec /// The instance for the current event. private static void OnAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - static void OnAnimationsChanged(IObservableVector sender, IVectorChangedEventArgs args) + static void OnAnimationsChanged(object sender, EventArgs e) { var collection = (ImplicitAnimationSet)sender; @@ -210,15 +211,15 @@ static void OnAnimationsChanged(IObservableVector sender, IVec if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.VectorChanged -= OnAnimationsChanged; + oldCollection.AnimationsChanged -= OnAnimationsChanged; } if (d is UIElement element && e.NewValue is ImplicitAnimationSet collection) { collection.ParentReference = new(element); - collection.VectorChanged -= OnAnimationsChanged; - collection.VectorChanged += OnAnimationsChanged; + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index eda7836e7f4..b07fcd74ecc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics.Contracts; +using Windows.Foundation.Collections; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; @@ -18,6 +19,48 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed class ImplicitAnimationSet : DependencyObjectCollection { + /// + /// Raised whenever any configuration change occurrs within the current instance. + /// + internal event EventHandler? AnimationsChanged; + + /// + /// Initializes a new instance of the class. + /// + public ImplicitAnimationSet() + { + VectorChanged += this.ImplicitAnimationSetVectorChanged; + } + + /// + /// Registers for every added animation. + /// + /// The current vector of animations. + /// The instance for the current event. + private void ImplicitAnimationSetVectorChanged(IObservableVector sender, IVectorChangedEventArgs @event) + { + if (@event.CollectionChange == CollectionChange.ItemInserted || + @event.CollectionChange == CollectionChange.ItemChanged) + { + IInternalImplicitAnimation item = (IInternalImplicitAnimation)sender[(int)@event.Index]; + + item.AnimationPropertyChanged -= RaiseAnimationsChanged; + item.AnimationPropertyChanged += RaiseAnimationsChanged; + } + + AnimationsChanged?.Invoke(this, EventArgs.Empty); + } + + /// + /// Raisess the event. + /// + /// The instance raising the event. + /// The empty for the event. + private void RaiseAnimationsChanged(object sender, EventArgs e) + { + AnimationsChanged?.Invoke(this, e); + } + /// /// Gets or sets the weak reference to the parent that owns the current implicit animation collection. /// From 9ab452fa234a5d79cca12404b8537fa6307d3bdc Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 16 Mar 2021 23:53:23 +0100 Subject: [PATCH 3/6] Improved XML docs for ImplicitAnimationSet --- .../Implicit.cs | 1 - .../Xaml/ImplicitAnimationSet.cs | 28 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs index ab2bda58beb..bc78c955b01 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index b07fcd74ecc..768d1c89c7d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -14,9 +14,29 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A collection of implicit animations that can be grouped together. This type represents a composite animation - /// (such as ) that is executed on a given element. + /// A collection of implicit animations that can be assigned to a and configured to be run automatically + /// when the element is either shown or hidden (through and , + /// or whenever one of the targeted properties on the underlying element changes, through . + /// + /// Animations within an should be objects implementing the interface, such as + /// types inheriting from (eg. , , + /// and , or custom ones such as and ). + /// Adding incompatible elements cannot be validated at build-time, but will result in a runtime crash. + /// + /// + /// Animations will monitor for changes in real-time to any of their public properties. For instance, if a binding is used to dynamically update the + /// to properties, the entire animation set will be + /// initialized again and assigned to the underlyign object for the targeted . This does not currently apply + /// to changes to the property though (other than the entire property being reassigned). To achieve + /// dynamic updates to animation sets in that case, either leverage expression keyframes or just use code-behind to manually reinitialize the animations. + /// /// + /// + /// An instance can only be used on a single target , and it cannot be shared across multiple + /// elements. Attempting to do so will result in a runtime crash. Furthermore, it is recommended not to move instances from + /// one to another, and doing so might add unnecessary runtime overhead over time. If you want to apply the same animations + /// to multiple elements, simply create another instance and another set of animations with the same properties within it. + /// public sealed class ImplicitAnimationSet : DependencyObjectCollection { /// @@ -29,7 +49,7 @@ public sealed class ImplicitAnimationSet : DependencyObjectCollection /// public ImplicitAnimationSet() { - VectorChanged += this.ImplicitAnimationSetVectorChanged; + VectorChanged += ImplicitAnimationSetVectorChanged; } /// @@ -52,7 +72,7 @@ private void ImplicitAnimationSetVectorChanged(IObservableVector - /// Raisess the event. + /// Raises the event. /// /// The instance raising the event. /// The empty for the event. From 1ab4b47786d5dd0d931d4fe0cb709132ec411fb1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 18 Mar 2021 19:51:07 +0100 Subject: [PATCH 4/6] Minor XML docs tweaks, fixed some typos --- .../Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs | 2 +- .../Xaml/ImplicitAnimationSet.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 6e5c58e9ecb..dc922b736de 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -96,7 +96,7 @@ public CompositionAnimation GetAnimation(UIElement element, out string? target) } /// - /// Raises event. + /// Raises the event. /// /// The instance raising the event. /// The that was changed. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index 768d1c89c7d..949c58a60da 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -15,8 +15,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A collection of implicit animations that can be assigned to a and configured to be run automatically - /// when the element is either shown or hidden (through and , - /// or whenever one of the targeted properties on the underlying element changes, through . + /// when the element is either shown or hidden (through and ), + /// or whenever one of the targeted properties on the underlying element changes (through ). /// /// Animations within an should be objects implementing the interface, such as /// types inheriting from (eg. , , @@ -25,16 +25,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// /// Animations will monitor for changes in real-time to any of their public properties. For instance, if a binding is used to dynamically update the - /// to properties, the entire animation set will be - /// initialized again and assigned to the underlyign object for the targeted . This does not currently apply + /// or properties, the entire animation set will be + /// initialized again and assigned to the underlying object for the targeted . This does not currently apply /// to changes to the property though (other than the entire property being reassigned). To achieve /// dynamic updates to animation sets in that case, either leverage expression keyframes or just use code-behind to manually reinitialize the animations. /// /// /// - /// An instance can only be used on a single target , and it cannot be shared across multiple + /// An instance can only be used on a single target, and it cannot be shared across multiple /// elements. Attempting to do so will result in a runtime crash. Furthermore, it is recommended not to move instances from - /// one to another, and doing so might add unnecessary runtime overhead over time. If you want to apply the same animations + /// one to another, and doing so will add unnecessary runtime overhead over time. If you want to apply the same animations /// to multiple elements, simply create another instance and another set of animations with the same properties within it. /// public sealed class ImplicitAnimationSet : DependencyObjectCollection From e18c3bb8bbea4c4b572e268bdf1673bd425469c1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 18 Mar 2021 22:08:34 +0100 Subject: [PATCH 5/6] Minor code tweaks to parent references for implicit sets --- .../Implicit.cs | 12 ++++---- .../Xaml/ImplicitAnimationSet.cs | 28 +++---------------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs index bc78c955b01..61cfb365389 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs @@ -136,7 +136,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) if (collection.ParentReference!.TryGetTarget(out UIElement element)) { - ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); + ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup(element)); } } @@ -153,7 +153,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) collection.AnimationsChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); - ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); + ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup(element)); } } @@ -170,7 +170,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) if (collection.ParentReference!.TryGetTarget(out UIElement element)) { - ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); + ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup(element)); } } @@ -187,7 +187,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) collection.AnimationsChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); - ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); + ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup(element)); } } @@ -204,7 +204,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) if (collection.ParentReference!.TryGetTarget(out UIElement element)) { - ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); + ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(element); } } @@ -221,7 +221,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) collection.AnimationsChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); - ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); + ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(element); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index 949c58a60da..db11b91a3ca 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -90,11 +90,11 @@ private void RaiseAnimationsChanged(object sender, EventArgs e) /// Creates a for the current collection. /// This can be used to be assigned to show/hide implicit composition animations. /// + /// The target to which the animations are being applied to. /// The instance to use. [Pure] - internal CompositionAnimationGroup GetCompositionAnimationGroup() + internal CompositionAnimationGroup GetCompositionAnimationGroup(UIElement parent) { - UIElement parent = GetParent(); Compositor compositor = ElementCompositionPreview.GetElementVisual(parent).Compositor; CompositionAnimationGroup animations = compositor.CreateAnimationGroup(); @@ -110,11 +110,11 @@ internal CompositionAnimationGroup GetCompositionAnimationGroup() /// Creates an for the current collection. /// This can be used to be assigned to implicit composition animations. /// + /// The target to which the animations are being applied to. /// The instance to use. [Pure] - internal ImplicitAnimationCollection GetImplicitAnimationCollection() + internal ImplicitAnimationCollection GetImplicitAnimationCollection(UIElement parent) { - UIElement parent = GetParent(); Compositor compositor = ElementCompositionPreview.GetElementVisual(parent).Compositor; ImplicitAnimationCollection animations = compositor.CreateImplicitAnimationCollection(); @@ -134,25 +134,5 @@ internal ImplicitAnimationCollection GetImplicitAnimationCollection() return animations; } - - /// - /// Gets the current parent instance. - /// - /// The reference from . - /// Thrown if there is no parent available. - [Pure] - private UIElement GetParent() - { - UIElement? parent = null; - - if (ParentReference?.TryGetTarget(out parent) != true) - { - ThrowInvalidOperationException(); - } - - return parent!; - - static void ThrowInvalidOperationException() => throw new InvalidOperationException("The current ImplicitAnimationSet object isn't bound to a parent UIElement instance."); - } } } From 4bc18c7b15000f99a068afe8a5cf193db0cf7613 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Mar 2021 00:37:56 +0100 Subject: [PATCH 6/6] Removed IInternalImplicitAnimation, moved event to public interface See https://github.com/windows-toolkit/WindowsCommunityToolkit/pull/3843#discussion_r597218969 --- .../ImplicitAnimation{TValue,TKeyFrame}.cs | 13 +++-------- .../Xaml/ImplicitAnimationSet.cs | 2 +- .../Xaml/Interfaces/IImplicitTimeline.cs | 8 +++++++ .../Interfaces/IInternalImplicitAnimation.cs | 22 ------------------- 4 files changed, 12 insertions(+), 33 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index dc922b736de..ac13e522558 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -15,11 +15,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// A base model representing a typed animation that can be used as an implicit composition animation. /// /// - public abstract class ImplicitAnimation : Animation, IImplicitTimeline, IInternalImplicitAnimation + public abstract class ImplicitAnimation : Animation, IImplicitTimeline where TKeyFrame : unmanaged { - /// - private event EventHandler? AnimationPropertyChanged; + /// + public event EventHandler? AnimationPropertyChanged; /// /// Initializes a new instance of the class. @@ -37,13 +37,6 @@ protected ImplicitAnimation() RegisterPropertyChangedCallback(KeyFramesProperty, RaiseAnimationPropertyChanged); } - /// - event EventHandler? IInternalImplicitAnimation.AnimationPropertyChanged - { - add => AnimationPropertyChanged += value; - remove => AnimationPropertyChanged -= value; - } - /// /// Gets or sets the optional implicit target for the animation. This can act as a trigger property for the animation. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index db11b91a3ca..b6eb2f259f9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -62,7 +62,7 @@ private void ImplicitAnimationSetVectorChanged(IObservableVector public interface IImplicitTimeline { + /// + /// Raised whenever a property that influences the animation changes. + /// This event is used by to update the animations collection + /// assigned to a target when any of the individual animations is modified. + /// + event EventHandler? AnimationPropertyChanged; + /// /// Gets a from the current node. This animation might /// be used either as an implicit show/hide animation, or as a direct implicit animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs deleted file mode 100644 index e83a427ff3c..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IInternalImplicitAnimation.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -#nullable enable - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// An interface adding notification support to implicit animations. This is needed to - /// avoid the type parameters when the event is subscribed to from . - /// - internal interface IInternalImplicitAnimation - { - /// - /// Raised whenever a property that influences the animation changes. - /// - event EventHandler? AnimationPropertyChanged; - } -}