From d766b9ee59e8e98b8c10c967019be66b32b7af80 Mon Sep 17 00:00:00 2001 From: Darren Batchelor Date: Tue, 12 Oct 2021 09:58:51 -0700 Subject: [PATCH 1/5] Initial commit --- .../ViewportBehaviorPage.xaml | 2 +- .../Viewport/ViewportBehavior.Properties.cs | 19 ++++++++++++++++ .../Viewport/ViewportBehavior.cs | 22 +++++++++---------- 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml index 6db0bbda012..510d205831e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml @@ -7,7 +7,7 @@ xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" mc:Ignorable="d"> - + diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs new file mode 100644 index 00000000000..1cfc1c53150 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs @@ -0,0 +1,19 @@ +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Behaviors +{ + public partial class ViewportBehavior + { + public static readonly DependencyProperty IsAlwaysOnProperty = + DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(true)); + + /// + /// Gets or sets a value indicating whether this behavior will remain attached after the associated element enters the viewport. When false, the behavior will remove itself after entering. + /// + public bool IsAlwaysOn + { + get { return (bool)GetValue(IsAlwaysOnProperty); } + set { SetValue(IsAlwaysOnProperty, value); } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs index abbf12238d1..cc82e97880c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs @@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Behaviors /// /// A class for listening element enter or exit the ScrollViewer viewport /// - public class ViewportBehavior : BehaviorBase + public partial class ViewportBehavior : BehaviorBase { /// /// The ScrollViewer hosting this element. @@ -36,8 +36,8 @@ public class ViewportBehavior : BehaviorBase /// /// The IsAlwaysOn value of the associated element /// - public static readonly DependencyProperty IsAlwaysOnProperty = - DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(default(bool))); + //public static readonly DependencyProperty IsAlwaysOnProperty = + // DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(true)); /// /// Associated element fully enter the ScrollViewer viewport event @@ -59,14 +59,14 @@ public class ViewportBehavior : BehaviorBase /// public event EventHandler ExitingViewport; - /// - /// Gets or sets a value indicating whether this behavior will remain attached after the associated element enters the viewport. When false, the behavior will remove itself after entering. - /// - public bool IsAlwaysOn - { - get { return (bool)GetValue(IsAlwaysOnProperty); } - set { SetValue(IsAlwaysOnProperty, value); } - } + ///// + ///// Gets or sets a value indicating whether this behavior will remain attached after the associated element enters the viewport. When false, the behavior will remove itself after entering. + ///// + //public bool IsAlwaysOn + //{ + // get { return (bool)GetValue(IsAlwaysOnProperty); } + // set { SetValue(IsAlwaysOnProperty, value); } + //} /// /// Gets a value indicating whether associated element is fully in the ScrollViewer viewport From 7ef191888a9c67066b02fb27eeee84b640aecc89 Mon Sep 17 00:00:00 2001 From: Darren Batchelor Date: Wed, 13 Oct 2021 16:35:37 -0700 Subject: [PATCH 2/5] Moved code into *.Properties.cs file, wired up IsAlwaysOn flag --- .../ViewportBehaviorPage.xaml | 2 +- .../ViewportBehaviorXaml.bind | 2 +- .../Viewport/ViewportBehavior.Properties.cs | 80 +++++++++++++++++++ .../Viewport/ViewportBehavior.cs | 78 ------------------ 4 files changed, 82 insertions(+), 80 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml index 510d205831e..6db0bbda012 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml @@ -7,7 +7,7 @@ xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" mc:Ignorable="d"> - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind index e749fca1e59..a50ae10887a 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind @@ -14,7 +14,7 @@ Height="200" Background="Gray"> - + + /// The IsFullyInViewport value of the associated element + /// + public static readonly DependencyProperty IsFullyInViewportProperty = + DependencyProperty.Register(nameof(IsFullyInViewport), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(default(bool), OnIsFullyInViewportChanged)); + + /// + /// The IsInViewport value of the associated element + /// + public static readonly DependencyProperty IsInViewportProperty = + DependencyProperty.Register(nameof(IsInViewport), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(default(bool), OnIsInViewportChanged)); + + /// + /// The IsAlwaysOn value of the associated element + /// public static readonly DependencyProperty IsAlwaysOnProperty = DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(true)); @@ -15,5 +31,69 @@ public bool IsAlwaysOn get { return (bool)GetValue(IsAlwaysOnProperty); } set { SetValue(IsAlwaysOnProperty, value); } } + + /// + /// Gets a value indicating whether associated element is fully in the ScrollViewer viewport + /// + public bool IsFullyInViewport + { + get { return (bool)GetValue(IsFullyInViewportProperty); } + private set { SetValue(IsFullyInViewportProperty, value); } + } + + /// + /// Gets a value indicating whether associated element is in the ScrollViewer viewport + /// + public bool IsInViewport + { + get { return (bool)GetValue(IsInViewportProperty); } + private set { SetValue(IsInViewportProperty, value); } + } + + /// + /// Event tracking when the object is fully within the viewport or not + /// + /// ViewportBehavior + /// EventArgs + private static void OnIsFullyInViewportChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var obj = (ViewportBehavior)d; + var value = (bool)e.NewValue; + + if (obj.IsAlwaysOn) + { + if (value) + { + obj.EnteredViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + } + else + { + obj.ExitingViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + } + } + } + + /// + /// Event tracking the state of the object as it moves in and out of the viewport + /// + /// ViewportBehavior + /// EventArgs + private static void OnIsInViewportChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var obj = (ViewportBehavior)d; + var value = (bool)e.NewValue; + + if (obj.IsAlwaysOn) + { + if (value) + { + obj.EnteringViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + } + else + { + obj.ExitedViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + } + } + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs index cc82e97880c..306891ffc85 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs @@ -21,24 +21,6 @@ public partial class ViewportBehavior : BehaviorBase /// private ScrollViewer _hostScrollViewer; - /// - /// The IsFullyInViewport value of the associated element - /// - public static readonly DependencyProperty IsFullyInViewportProperty = - DependencyProperty.Register(nameof(IsFullyInViewport), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(default(bool), OnIsFullyInViewportChanged)); - - /// - /// The IsInViewport value of the associated element - /// - public static readonly DependencyProperty IsInViewportProperty = - DependencyProperty.Register(nameof(IsInViewport), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(default(bool), OnIsInViewportChanged)); - - /// - /// The IsAlwaysOn value of the associated element - /// - //public static readonly DependencyProperty IsAlwaysOnProperty = - // DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(true)); - /// /// Associated element fully enter the ScrollViewer viewport event /// @@ -59,33 +41,6 @@ public partial class ViewportBehavior : BehaviorBase /// public event EventHandler ExitingViewport; - ///// - ///// Gets or sets a value indicating whether this behavior will remain attached after the associated element enters the viewport. When false, the behavior will remove itself after entering. - ///// - //public bool IsAlwaysOn - //{ - // get { return (bool)GetValue(IsAlwaysOnProperty); } - // set { SetValue(IsAlwaysOnProperty, value); } - //} - - /// - /// Gets a value indicating whether associated element is fully in the ScrollViewer viewport - /// - public bool IsFullyInViewport - { - get { return (bool)GetValue(IsFullyInViewportProperty); } - private set { SetValue(IsFullyInViewportProperty, value); } - } - - /// - /// Gets a value indicating whether associated element is in the ScrollViewer viewport - /// - public bool IsInViewport - { - get { return (bool)GetValue(IsInViewportProperty); } - private set { SetValue(IsInViewportProperty, value); } - } - /// /// Called after the behavior is attached to the . /// @@ -120,39 +75,6 @@ protected override void OnDetaching() _hostScrollViewer = null; } - private static void OnIsFullyInViewportChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var obj = (ViewportBehavior)d; - var value = (bool)e.NewValue; - if (value) - { - obj.EnteredViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - - if (!obj.IsAlwaysOn) - { - Interaction.GetBehaviors(obj.AssociatedObject).Remove(obj); - } - } - else - { - obj.ExitingViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - } - } - - private static void OnIsInViewportChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var obj = (ViewportBehavior)d; - var value = (bool)e.NewValue; - if (value) - { - obj.EnteringViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - } - else - { - obj.ExitedViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - } - } - private void ParentScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { var associatedElementRect = AssociatedObject.TransformToVisual(_hostScrollViewer) From 722dbb03c97ce2ac23611d01018c669d864a7760 Mon Sep 17 00:00:00 2001 From: Darren Batchelor Date: Thu, 14 Oct 2021 09:37:30 -0700 Subject: [PATCH 3/5] update params comment --- .../Viewport/ViewportBehavior.Properties.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs index fce02d3110a..0d3d0799962 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs @@ -53,7 +53,7 @@ public bool IsInViewport /// /// Event tracking when the object is fully within the viewport or not /// - /// ViewportBehavior + /// DependencyObject /// EventArgs private static void OnIsFullyInViewportChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { @@ -74,9 +74,9 @@ private static void OnIsFullyInViewportChanged(DependencyObject d, DependencyPro } /// - /// Event tracking the state of the object as it moves in and out of the viewport + /// Event tracking the state of the object as it moves into and out of the viewport /// - /// ViewportBehavior + /// DependencyObject /// EventArgs private static void OnIsInViewportChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { From 0ce0cf3a2d14b4b1340fc0a51563b1352f31b83d Mon Sep 17 00:00:00 2001 From: Darren Batchelor Date: Thu, 14 Oct 2021 14:01:31 -0700 Subject: [PATCH 4/5] Bring back original impl, set IsAlwaysOn in Sample page to true --- .../ViewportBehaviorXaml.bind | 2 +- .../Viewport/ViewportBehavior.Properties.cs | 38 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind index a50ae10887a..d51a7f245d6 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorXaml.bind @@ -14,7 +14,7 @@ Height="200" Background="Gray"> - + public static readonly DependencyProperty IsAlwaysOnProperty = - DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(true)); + DependencyProperty.Register(nameof(IsAlwaysOn), typeof(bool), typeof(ViewportBehavior), new PropertyMetadata(default(bool))); /// /// Gets or sets a value indicating whether this behavior will remain attached after the associated element enters the viewport. When false, the behavior will remove itself after entering. @@ -60,17 +65,19 @@ private static void OnIsFullyInViewportChanged(DependencyObject d, DependencyPro var obj = (ViewportBehavior)d; var value = (bool)e.NewValue; - if (obj.IsAlwaysOn) + if (value) { - if (value) - { - obj.EnteredViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - } - else + obj.EnteredViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + + if (!obj.IsAlwaysOn) { - obj.ExitingViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + Interaction.GetBehaviors(obj.AssociatedObject).Remove(obj); } } + else + { + obj.ExitingViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + } } /// @@ -83,16 +90,13 @@ private static void OnIsInViewportChanged(DependencyObject d, DependencyProperty var obj = (ViewportBehavior)d; var value = (bool)e.NewValue; - if (obj.IsAlwaysOn) + if (value) { - if (value) - { - obj.EnteringViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - } - else - { - obj.ExitedViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); - } + obj.EnteringViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); + } + else + { + obj.ExitedViewport?.Invoke(obj.AssociatedObject, EventArgs.Empty); } } } From 74021fbac758d3ec4212ef3e7ea7622f39f80523 Mon Sep 17 00:00:00 2001 From: Darren Batchelor Date: Fri, 15 Oct 2021 10:07:01 -0700 Subject: [PATCH 5/5] Address CI build errors --- .../Viewport/ViewportBehavior.Properties.cs | 5 ++++- .../Viewport/ViewportBehavior.cs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs index d96dbaa9c9f..344cfdce317 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.Properties.cs @@ -2,12 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Xaml.Interactivity; using System; +using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Behaviors { + /// + /// A class for listening to an element enter or exit the ScrollViewer viewport + /// public partial class ViewportBehavior { /// diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs index 306891ffc85..ed2e6206c19 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// - /// A class for listening element enter or exit the ScrollViewer viewport + /// A class for listening to an element enter or exit the ScrollViewer viewport /// public partial class ViewportBehavior : BehaviorBase {