diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 6b2945ec7b1..fb9c276db82 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -605,6 +605,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsCode.bind index d65a810e70b..d6969770a7f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsCode.bind @@ -1,71 +1,10 @@ - +// C# - Scale can be applied to any UIElement. In this case it is an image called ToolkitLogo. +using Microsoft.Toolkit.Uwp.UI.Extensions; - - - +// Binds the Y scroll axis of the ScrollViewer to the Y translation axis of the target +listScrollViewer.StartExpressionAnimation(shapesPanel, Axis.Y); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +// It is also possible to synchronize different axes, as well as targeting +// different Visual properties. By default, the expression works with the +// Visual.Translate property, but Visual.Offset can be used as well. +listScrollViewer.StartExpressionAnimation(shapesPanel, Axis.X, Axis.Y, VisualProperty.Offset); \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml index 44271197c6f..08bf65c2e7c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml @@ -40,8 +40,7 @@ - + @@ -66,5 +65,46 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml.cs index eb277d11860..8cea51a5441 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml.cs @@ -4,11 +4,9 @@ using System.Collections.ObjectModel; using Microsoft.Toolkit.Uwp.SampleApp.Models; -using Microsoft.Toolkit.Uwp.UI.Controls; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Navigation; namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages { @@ -35,6 +33,14 @@ public void OnXamlRendered(FrameworkElement control) if (listView != null) { listView.ItemsSource = _items; + + var shapesPanel = control.FindChildByName("shapesPanel") as StackPanel; + if (shapesPanel != null) + { + var listScrollViewer = listView.FindDescendant(); + + listScrollViewer?.StartExpressionAnimation(shapesPanel, Axis.Y); + } } } } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind new file mode 100644 index 00000000000..59737c4f9a2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index e9d073474f2..686f11736fc 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -1235,7 +1235,8 @@ "Type": "ScrollViewerExtensionsPage", "About": "Extensions for all controls that contain a ScrollViewer like ListView.", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer", - "XamlCodeFile": "ScrollViewerExtensionsCode.bind", + "XamlCodeFile": "ScrollViewerExtensionsXaml.bind", + "CodeFile": "ScrollViewerExtensionsCode.bind", "Icon": "/Assets/Helpers.png", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/ScrollViewerExtensions.md" }, diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/Enums/Axis.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/Enums/Axis.cs new file mode 100644 index 00000000000..6be7a01a3f6 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/Enums/Axis.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. + +namespace Microsoft.Toolkit.Uwp.UI.Extensions +{ + /// + /// Indicates an axis in the 2D space + /// + public enum Axis + { + /// + /// The X axis (horizontal) + /// + X, + + /// + /// The Y axis (vertical) + /// + Y + } +} diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/Enums/VisualProperty.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/Enums/VisualProperty.cs new file mode 100644 index 00000000000..2ec4967ce02 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/Enums/VisualProperty.cs @@ -0,0 +1,24 @@ +// 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 Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Extensions +{ + /// + /// Indicates a property of a object. + /// + public enum VisualProperty + { + /// + /// The offset property of a object. + /// + Offset, + + /// + /// The translation property of a object. + /// + Translation + } +} diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.ExpressionAnimations.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.ExpressionAnimations.cs new file mode 100644 index 00000000000..a7624a7f0cf --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.ExpressionAnimations.cs @@ -0,0 +1,75 @@ +// 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; +using System.Numerics; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Hosting; + +namespace Microsoft.Toolkit.Uwp.UI.Extensions +{ + /// + /// Provides attached dependency properties and methods for the control. + /// + public static partial class ScrollViewerExtensions + { + /// + /// Creates and starts an animation on the target element that binds either the X or Y axis of the source . + /// + /// The source control to use. + /// The target that will be animated. + /// The scrolling axis of the source . + /// The target property to animate. + /// An instance that represents an already running animation. + public static ExpressionAnimation StartExpressionAnimation( + this ScrollViewer scroller, + UIElement target, + Axis axis, + VisualProperty property = VisualProperty.Translation) + { + return scroller.StartExpressionAnimation(target, axis, axis, property); + } + + /// + /// Creates and starts an animation on the target element that binds either the X or Y axis of the source + /// + /// The source control to use + /// The target that will be animated + /// The scrolling axis of the source + /// The optional scrolling axis of the target element, if the source axis will be used + /// The target property to animate. + /// An instance that represents an already running animation. + public static ExpressionAnimation StartExpressionAnimation( + this ScrollViewer scroller, + UIElement target, + Axis sourceAxis, + Axis targetAxis, + VisualProperty property = VisualProperty.Translation) + { + CompositionPropertySet scrollSet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scroller); + + ExpressionAnimation animation = scrollSet.Compositor.CreateExpressionAnimation($"{nameof(scroller)}.{nameof(UIElement.Translation)}.{sourceAxis}"); + + animation.SetReferenceParameter(nameof(scroller), scrollSet); + + Visual visual = ElementCompositionPreview.GetElementVisual(target); + + switch (property) + { + case VisualProperty.Translation: + ElementCompositionPreview.SetIsTranslationEnabled(target, true); + visual.StartAnimation($"{nameof(Matrix4x4.Translation)}.{targetAxis}", animation); + break; + case VisualProperty.Offset: + visual.StartAnimation($"{nameof(Visual.Offset)}.{targetAxis}", animation); + break; + default: throw new ArgumentException($"Invalid target property: {property}", nameof(property)); + } + + return animation; + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.MiddleClickScrolling.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.MiddleClickScrolling.cs index ed252e38bc0..92eb76405f1 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.MiddleClickScrolling.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.MiddleClickScrolling.cs @@ -15,7 +15,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Extensions { /// - /// Provides attached dependency properties for the to scroll with middle click + /// Provides attached dependency properties and methods for the control. /// public static partial class ScrollViewerExtensions { diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.Properties.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.Properties.cs index 16c6b02fc37..fcb8adf1373 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.Properties.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.Properties.cs @@ -7,7 +7,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Extensions { /// - /// Provides attached dependency properties for the + /// Provides attached dependency properties and methods for the control. /// public partial class ScrollViewerExtensions { diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.cs index 4549a53b550..07f880b029c 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/ScrollViewerExtensions.cs @@ -2,7 +2,6 @@ // 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 System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -11,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Extensions { /// - /// Provides attached dependency properties for the + /// Provides attached dependency properties and methods for the control. /// public static partial class ScrollViewerExtensions {