diff --git a/src/Uno.UI/Generated/3.0.0.0/Windows.UI.Xaml.Controls/ScrollContentPresenter.cs b/src/Uno.UI/Generated/3.0.0.0/Windows.UI.Xaml.Controls/ScrollContentPresenter.cs
index 4fc89a79859a..1cff6cb9c9d7 100644
--- a/src/Uno.UI/Generated/3.0.0.0/Windows.UI.Xaml.Controls/ScrollContentPresenter.cs
+++ b/src/Uno.UI/Generated/3.0.0.0/Windows.UI.Xaml.Controls/ScrollContentPresenter.cs
@@ -176,14 +176,14 @@ public void MouseWheelRight()
global::Windows.Foundation.Metadata.ApiInformation.TryRaiseNotImplemented("Windows.UI.Xaml.Controls.ScrollContentPresenter", "void ScrollContentPresenter.MouseWheelRight()");
}
#endif
- #if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
+ #if __ANDROID__ || __IOS__ || NET461 || false || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__NETSTD_REFERENCE__")]
public void SetHorizontalOffset( double offset)
{
global::Windows.Foundation.Metadata.ApiInformation.TryRaiseNotImplemented("Windows.UI.Xaml.Controls.ScrollContentPresenter", "void ScrollContentPresenter.SetHorizontalOffset(double offset)");
}
#endif
- #if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
+ #if __ANDROID__ || __IOS__ || NET461 || false || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__NETSTD_REFERENCE__")]
public void SetVerticalOffset( double offset)
{
diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.Managed.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.Managed.cs
index 6e0bd2f7932c..35d3b337f8c1 100644
--- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.Managed.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.Managed.cs
@@ -19,61 +19,6 @@ namespace Windows.UI.Xaml.Controls
{
public partial class ScrollContentPresenter : ContentPresenter, ICustomClippingElement
{
- // Default physical amount to scroll with Up/Down/Left/Right key
- //const double ScrollViewerLineDelta = 16.0;
-
- // This value comes from WHEEL_DELTA defined in WinUser.h. It represents the universal default mouse wheel delta.
- const int ScrollViewerDefaultMouseWheelDelta = 120;
-
- // These macros compute how many integral pixels need to be scrolled based on the viewport size and mouse wheel delta.
- // - First the maximum between 48 and 15% of the viewport size is picked.
- // - Then that number is multiplied by (mouse wheel delta/120), 120 being the universal default value.
- // - Finally if the resulting number is larger than the viewport size, then that viewport size is picked instead.
- private static double GetVerticalScrollWheelDelta(Size size, double delta)
- => Math.Min(Math.Floor(size.Height), Math.Round(delta * Math.Max(48.0, Math.Round(size.Height * 0.15, 0)) / ScrollViewerDefaultMouseWheelDelta, 0));
- private static double GetHorizontalScrollWheelDelta(Size size, double delta)
- => Math.Min(Math.Floor(size.Width), Math.Round(delta * Math.Max(48.0, Math.Round(size.Width * 0.15, 0)) / ScrollViewerDefaultMouseWheelDelta, 0));
-
- // Minimum value of MinZoomFactor, ZoomFactor and MaxZoomFactor
- // ZoomFactor can be manipulated to a slightly smaller value, but
- // will jump back to 0.1 when the manipulation completes.
- //const double ScrollViewerMinimumZoomFactor = 0.1f;
-
- // Tolerated rounding delta in pixels between requested scroll offset and
- // effective value. Used to handle non-DM-driven scrolls.
- //const double ScrollViewerScrollRoundingTolerance = 0.05f;
-
- // Tolerated rounding delta in pixels between requested scroll offset and
- // effective value for cases where IScrollInfo is implemented by a
- // IManipulationDataProvider provider. Used to handle non-DM-driven scrolls.
- //const double ScrollViewerScrollRoundingToleranceForProvider = 1.0f;
-
- // Delta required between the current scroll offsets and target scroll offsets
- // in order to warrant a call to BringIntoViewport instead of
- // SetOffsetsWithExtents, SetHorizontalOffset, SetVerticalOffset.
- //const double ScrollViewerScrollRoundingToleranceForBringIntoViewport = 0.001f;
-
- // Tolerated rounding delta in between requested zoom factor and
- // effective value. Used to handle non-DM-driven zooms.
- //const double ScrollViewerZoomExtentRoundingTolerance = 0.001f;
-
- // Tolerated rounding delta in between old and new zoom factor
- // in DM delta handling.
- //const double ScrollViewerZoomRoundingTolerance = 0.000001f;
-
- // Delta required between the current zoom factor and target zoom factor
- // in order to warrant a call to BringIntoViewport instead of ZoomToFactor.
- //const double ScrollViewerZoomRoundingToleranceForBringIntoViewport = 0.00001f;
-
- // When a snap point is within this tolerance of the scrollviewer's extent
- // minus its viewport we nudge the snap point back into place.
- //const double ScrollViewerSnapPointLocationTolerance = 0.0001f;
-
- // If a ScrollViewer is going to reflow around docked CoreInputView occlussions
- // by shrinking its viewport, we want to at least guarantee that it will keep
- // an appropriate size.
- //const double ScrollViewerMinHeightToReflowAroundOcclusions = 32.0f;
-
private /*readonly - partial*/ IScrollStrategy _strategy;
private bool _canHorizontallyScroll;
@@ -123,7 +68,7 @@ partial void InitializePartial()
_strategy.Initialize(this);
// Mouse wheel support
- PointerWheelChanged += ScrollContentPresenter_PointerWheelChanged;
+ PointerWheelChanged += PointerWheelScroll;
// Touch scroll support
ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY; // Updated in PrepareTouchScroll!
@@ -132,12 +77,6 @@ partial void InitializePartial()
ManipulationCompleted += CompleteTouchScroll;
}
- public void SetVerticalOffset(double offset)
- => Set(verticalOffset: offset);
-
- public void SetHorizontalOffset(double offset)
- => Set(horizontalOffset: offset);
-
///
protected override void OnContentChanged(object oldValue, object newValue)
{
@@ -162,7 +101,7 @@ internal bool Set(
double? horizontalOffset = null,
double? verticalOffset = null,
float? zoomFactor = null,
- bool disableAnimation = true,
+ bool disableAnimation = false,
bool isIntermediate = false)
{
var success = true;
@@ -215,44 +154,6 @@ private void Apply(bool disableAnimation, bool isIntermediate)
InvalidateViewport();
}
- // Ensure the offset we're scrolling to is valid.
- private double ValidateInputOffset(double offset, int minOffset, double maxOffset)
- {
- if (offset.IsNaN())
- {
- throw new InvalidOperationException($"Invalid scroll offset value");
- }
-
- return Math.Max(minOffset, Math.Min(offset, maxOffset));
- }
-
- private void ScrollContentPresenter_PointerWheelChanged(object sender, Input.PointerRoutedEventArgs e)
- {
- var properties = e.GetCurrentPoint(null).Properties;
-
- if (Content is UIElement)
- {
- var canScrollHorizontally = CanHorizontallyScroll;
- var canScrollVertically = CanVerticallyScroll;
-
- if (e.KeyModifiers == VirtualKeyModifiers.Control)
- {
- // TODO: Handle zoom https://github.com/unoplatform/uno/issues/4309
- }
- else if (!canScrollVertically || properties.IsHorizontalMouseWheel || e.KeyModifiers == VirtualKeyModifiers.Shift)
- {
- if (canScrollHorizontally)
- {
- SetHorizontalOffset(HorizontalOffset + GetHorizontalScrollWheelDelta(DesiredSize, -properties.MouseWheelDelta * ScrollViewerDefaultMouseWheelDelta));
- }
- }
- else
- {
- SetVerticalOffset(VerticalOffset + GetVerticalScrollWheelDelta(DesiredSize, properties.MouseWheelDelta * ScrollViewerDefaultMouseWheelDelta));
- }
- }
- }
-
private void PrepareTouchScroll(object sender, ManipulationStartingRoutedEventArgs e)
{
if (e.Container != this)
@@ -289,6 +190,7 @@ private void UpdateTouchScroll(object sender, ManipulationDeltaRoutedEventArgs e
Set(
horizontalOffset: HorizontalOffset - e.Delta.Translation.X,
verticalOffset: VerticalOffset - e.Delta.Translation.Y,
+ disableAnimation: true,
isIntermediate: true);
}
@@ -299,7 +201,7 @@ private void CompleteTouchScroll(object sender, ManipulationCompletedRoutedEvent
return;
}
- Set(isIntermediate: false);
+ Set(disableAnimation: true, isIntermediate: false);
}
bool ICustomClippingElement.AllowClippingToLayoutSlot => true;
diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs
index 055c3e49b67e..f4ceecc569c9 100644
--- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs
@@ -2,6 +2,7 @@
using System;
using Windows.Foundation;
using Uno.UI;
+using Windows.System;
#if XAMARIN_ANDROID
using View = Android.Views.View;
using Font = Android.Graphics.Typeface;
@@ -182,7 +183,71 @@ protected override Size ArrangeOverride(Size finalSize)
internal override bool IsViewHit()
=> true;
-#elif __IOS__ // Note: No __ANDROID__, the ICustomScrollInfo support is made directly in the NativeScrollContentPresenter
+
+ private void PointerWheelScroll(object sender, Input.PointerRoutedEventArgs e)
+ {
+ var properties = e.GetCurrentPoint(null).Properties;
+
+ if (Content is UIElement)
+ {
+ var canScrollHorizontally = CanHorizontallyScroll;
+ var canScrollVertically = CanVerticallyScroll;
+ var delta = IsPointerWheelReversed
+ ? -properties.MouseWheelDelta
+ : properties.MouseWheelDelta;
+
+ if (e.KeyModifiers == VirtualKeyModifiers.Control)
+ {
+ // TODO: Handle zoom https://github.com/unoplatform/uno/issues/4309
+ }
+ else if (!canScrollVertically || properties.IsHorizontalMouseWheel || e.KeyModifiers == VirtualKeyModifiers.Shift)
+ {
+ if (canScrollHorizontally)
+ {
+#if __WASM__ // On wasm the scroll might be async (especially with disableAnimation: false), so we need to use the pending value to support high speed multiple wheel events
+ var horizontalOffset = _pendingScrollTo?.horizontal ?? HorizontalOffset;
+#else
+ var horizontalOffset = HorizontalOffset;
+#endif
+
+ Set(
+ horizontalOffset: horizontalOffset + GetHorizontalScrollWheelDelta(DesiredSize, delta),
+ disableAnimation: false);
+ }
+ }
+ else
+ {
+#if __WASM__ // On wasm the scroll might be async (especially with disableAnimation: false), so we need to use the pending value to support high speed multiple wheel events
+ var verticalOffset = _pendingScrollTo?.vertical ?? VerticalOffset;
+#else
+ var verticalOffset = VerticalOffset;
+#endif
+
+ Set(
+ verticalOffset: verticalOffset + GetVerticalScrollWheelDelta(DesiredSize, -delta),
+ disableAnimation: false);
+ }
+ }
+ }
+
+ public void SetVerticalOffset(double offset)
+ => Set(verticalOffset: offset, disableAnimation: true);
+
+ public void SetHorizontalOffset(double offset)
+ => Set(horizontalOffset: offset, disableAnimation: true);
+
+ // Ensure the offset we're scrolling to is valid.
+ private double ValidateInputOffset(double offset, int minOffset, double maxOffset)
+ {
+ if (offset.IsNaN())
+ {
+ throw new InvalidOperationException($"Invalid scroll offset value");
+ }
+
+ return Math.Max(minOffset, Math.Min(offset, maxOffset));
+ }
+
+#elif __IOS__ // Note: No __ANDROID__, the ICustomScrollInfo support is made directly in the NativeScrollContentPresenter
protected override Size MeasureOverride(Size size)
{
var result = base.MeasureOverride(size);
diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.mux.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.mux.cs
index f0b04eac8c6d..7d772fea20df 100644
--- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.mux.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.mux.cs
@@ -10,6 +10,62 @@ namespace Windows.UI.Xaml.Controls;
public partial class ScrollContentPresenter
{
+ // Default physical amount to scroll with Up/Down/Left/Right key
+ //const double ScrollViewerLineDelta = 16.0;
+
+ // This value comes from WHEEL_DELTA defined in WinUser.h. It represents the universal default mouse wheel delta.
+ internal const int ScrollViewerDefaultMouseWheelDelta = 120;
+
+ // These macros compute how many integral pixels need to be scrolled based on the viewport size and mouse wheel delta.
+ // - First the maximum between 48 and 15% of the viewport size is picked.
+ // - Then that number is multiplied by (mouse wheel delta/120), 120 being the universal default value.
+ // - Finally if the resulting number is larger than the viewport size, then that viewport size is picked instead.
+ private static double GetVerticalScrollWheelDelta(Size size, double delta)
+ => Math.Min(Math.Floor(size.Height), Math.Round(delta * Math.Max(48.0, Math.Round(size.Height * 0.15, 0)) / ScrollViewerDefaultMouseWheelDelta, 0));
+ private static double GetHorizontalScrollWheelDelta(Size size, double delta)
+ => Math.Min(Math.Floor(size.Width), Math.Round(delta * Math.Max(48.0, Math.Round(size.Width * 0.15, 0)) / ScrollViewerDefaultMouseWheelDelta, 0));
+
+ // Minimum value of MinZoomFactor, ZoomFactor and MaxZoomFactor
+ // ZoomFactor can be manipulated to a slightly smaller value, but
+ // will jump back to 0.1 when the manipulation completes.
+ //const double ScrollViewerMinimumZoomFactor = 0.1f;
+
+ // Tolerated rounding delta in pixels between requested scroll offset and
+ // effective value. Used to handle non-DM-driven scrolls.
+ //const double ScrollViewerScrollRoundingTolerance = 0.05f;
+
+ // Tolerated rounding delta in pixels between requested scroll offset and
+ // effective value for cases where IScrollInfo is implemented by a
+ // IManipulationDataProvider provider. Used to handle non-DM-driven scrolls.
+ //const double ScrollViewerScrollRoundingToleranceForProvider = 1.0f;
+
+ // Delta required between the current scroll offsets and target scroll offsets
+ // in order to warrant a call to BringIntoViewport instead of
+ // SetOffsetsWithExtents, SetHorizontalOffset, SetVerticalOffset.
+ //const double ScrollViewerScrollRoundingToleranceForBringIntoViewport = 0.001f;
+
+ // Tolerated rounding delta in between requested zoom factor and
+ // effective value. Used to handle non-DM-driven zooms.
+ //const double ScrollViewerZoomExtentRoundingTolerance = 0.001f;
+
+ // Tolerated rounding delta in between old and new zoom factor
+ // in DM delta handling.
+ //const double ScrollViewerZoomRoundingTolerance = 0.000001f;
+
+ // Delta required between the current zoom factor and target zoom factor
+ // in order to warrant a call to BringIntoViewport instead of ZoomToFactor.
+ //const double ScrollViewerZoomRoundingToleranceForBringIntoViewport = 0.00001f;
+
+ // When a snap point is within this tolerance of the scrollviewer's extent
+ // minus its viewport we nudge the snap point back into place.
+ //const double ScrollViewerSnapPointLocationTolerance = 0.0001f;
+
+ // If a ScrollViewer is going to reflow around docked CoreInputView occlussions
+ // by shrinking its viewport, we want to at least guarantee that it will keep
+ // an appropriate size.
+ //const double ScrollViewerMinHeightToReflowAroundOcclusions = 32.0f;
+
+
// BringIntoView functionality is ported from WinUI ScrollPresenter
// https://github.com/microsoft/microsoft-ui-xaml/blob/main/dev/ScrollPresenter/ScrollPresenter.cpp
// with partial modifications to match the ScrollViewer control behavior.
diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.uno.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.uno.cs
new file mode 100644
index 000000000000..a95a7b90577c
--- /dev/null
+++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.uno.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.UI.Xaml;
+
+namespace Uno.UI.Xaml.Controls
+{
+ public class ScrollContentPresenter
+ {
+ ///
+ /// Backing property for the IsPointerWheelReversed attached property.
+ ///
+ public static readonly DependencyProperty IsPointerWheelReversedProperty = DependencyProperty.RegisterAttached(
+ "IsPointerWheelReversed",
+ typeof(bool),
+ typeof(Windows.UI.Xaml.Controls.ScrollContentPresenter),
+ new FrameworkPropertyMetadata((snd, e) => ((Windows.UI.Xaml.Controls.ScrollContentPresenter)snd).IsPointerWheelReversed = (bool)e.NewValue));
+
+ ///
+ /// Gets a boolean which indicates if the pointer wheel should be reversed or not for the .
+ ///
+ ///
+ ///
+ public static bool GetIsPointerWheelReversed(Windows.UI.Xaml.Controls.ScrollContentPresenter scrollViewer)
+ => (bool)scrollViewer.GetValue(IsPointerWheelReversedProperty);
+
+ ///
+ /// Sets if the pointer wheel should be reversed or not for the .
+ ///
+ /// The target ScrollViewer to configure
+ /// A boolean which indicates if the wheel should be reversed of not.
+ public static void SetIsPointerWheelReversed(Windows.UI.Xaml.Controls.ScrollContentPresenter scrollViewer, bool isReversed)
+ => scrollViewer.SetValue(IsPointerWheelReversedProperty, isReversed);
+
+ }
+}
+
+namespace Windows.UI.Xaml.Controls
+{
+ partial class ScrollContentPresenter
+ {
+ private bool _isPointerWheelReversed;
+
+ ///
+ /// Cached value of ,
+ /// in order to not access the DP on each scroll (perf considerations)
+ ///
+ internal bool IsPointerWheelReversed
+ {
+ get => _isPointerWheelReversed;
+ set
+ {
+ if (_isPointerWheelReversed != value)
+ {
+ _isPointerWheelReversed = value;
+ OnIsPointerWheelReversedChanged(value);
+ }
+ }
+ }
+
+ partial void OnIsPointerWheelReversedChanged(bool isReversed);
+ }
+}
diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs
index de86c17b4f75..6dcdaf14504c 100644
--- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs
@@ -13,6 +13,7 @@
using Uno.UI.Xaml;
using Uno.UI.Extensions;
+using Uno.UI.Xaml.Input;
namespace Windows.UI.Xaml.Controls
{
@@ -37,6 +38,24 @@ internal Size ScrollBarSize
private object RealContent => Content;
+ partial void OnIsPointerWheelReversedChanged(bool isReversed)
+ {
+ PointerWheelChanged -= ManagedScroll;
+ if (isReversed)
+ {
+ PointerWheelChanged += ManagedScroll;
+ }
+
+ static void ManagedScroll(object sender, Input.PointerRoutedEventArgs e)
+ {
+ // When pointer wheel is reversed, we scroll in managed code and prevent the browser to scroll (PreventDefault)
+ e.Handled = true;
+ ((IHtmlHandleableRoutedEventArgs)e).HandledResult |= HtmlEventDispatchResult.PreventDefault;
+
+ ((ScrollContentPresenter)sender).PointerWheelScroll(sender, e);
+ }
+ }
+
private void TryRegisterEvents(ScrollBarVisibility visibility)
{
if (
@@ -49,20 +68,20 @@ private void TryRegisterEvents(ScrollBarVisibility visibility)
_eventsRegistered = true;
- PointerReleased += HandlePointerEvent;
- PointerPressed += HandlePointerEvent;
- PointerCanceled += HandlePointerEvent;
- PointerMoved += HandlePointerEvent;
- PointerEntered += HandlePointerEvent;
- PointerExited += HandlePointerEvent;
- PointerWheelChanged += HandlePointerEvent;
+ PointerReleased += HandlePointerEventIfOverNativeScrollbars;
+ PointerPressed += HandlePointerEventIfOverNativeScrollbars;
+ PointerCanceled += HandlePointerEventIfOverNativeScrollbars;
+ PointerMoved += HandlePointerEventIfOverNativeScrollbars;
+ PointerEntered += HandlePointerEventIfOverNativeScrollbars;
+ PointerExited += HandlePointerEventIfOverNativeScrollbars;
+ PointerWheelChanged += HandlePointerEventIfOverNativeScrollbars;
}
}
- private static void HandlePointerEvent(object sender, Input.PointerRoutedEventArgs e)
- => ((ScrollContentPresenter)sender).HandlePointerEvent(e);
+ private static void HandlePointerEventIfOverNativeScrollbars(object sender, Input.PointerRoutedEventArgs e)
+ => ((ScrollContentPresenter)sender).HandlePointerEventIfOverNativeScrollbars(e);
- private void HandlePointerEvent(Input.PointerRoutedEventArgs e)
+ private void HandlePointerEventIfOverNativeScrollbars(Input.PointerRoutedEventArgs e)
{
var (clientSize, offsetSize) = WindowManagerInterop.GetClientViewSize(HtmlId);
@@ -166,7 +185,10 @@ private void RestoreScroll()
{
if (sv.HorizontalOffset > 0 || sv.VerticalOffset > 0)
{
- ScrollTo(sv.HorizontalOffset, sv.VerticalOffset, disableAnimation: true);
+ Set(
+ horizontalOffset: sv.HorizontalOffset,
+ verticalOffset: sv.VerticalOffset,
+ disableAnimation: true);
}
}
}
@@ -191,8 +213,32 @@ internal override void OnLayoutUpdated()
TryProcessScrollTo();
}
- public void ScrollTo(double? horizontalOffset, double? verticalOffset, bool disableAnimation)
+ internal bool Set(
+ double? horizontalOffset = null,
+ double? verticalOffset = null,
+ float? zoomFactor = null, // Not supported yet
+ bool disableAnimation = false,
+ bool isIntermediate = false) // Not supported yet
{
+ var success = true;
+ if (horizontalOffset is double hOffset)
+ {
+ var extentWidth = ExtentWidth;
+ var viewportWidth = ViewportWidth;
+
+ horizontalOffset = ValidateInputOffset(hOffset, 0, extentWidth - viewportWidth);
+ success &= horizontalOffset == hOffset;
+ }
+
+ if (verticalOffset is double vOffset)
+ {
+ var extentHeight = ExtentHeight;
+ var viewportHeight = ViewportHeight;
+
+ verticalOffset = ValidateInputOffset(vOffset, 0, extentHeight - viewportHeight);
+ success &= verticalOffset == vOffset;
+ }
+
_pendingScrollTo = (horizontalOffset, verticalOffset);
WindowManagerInterop.ScrollTo(HtmlId, horizontalOffset, verticalOffset, disableAnimation);
@@ -228,7 +274,11 @@ public void ScrollTo(double? horizontalOffset, double? verticalOffset, bool disa
var willNotScroll = horizontalOffset < 0 && nativeHorizontalOffset == 0
|| verticalOffset < 0 && nativeVerticalOffset == 0;
- if (!willNotScroll)
+ if (willNotScroll)
+ {
+ return false;
+ }
+ else
{
// As the native ScrollTo is going to be async, we manually raise the event with the provided values.
// If those values are invalid, the browser will raise the final event anyway.
@@ -242,8 +292,17 @@ public void ScrollTo(double? horizontalOffset, double? verticalOffset, bool disa
}
}
}
+
+ return success; // If if not yet processed, we assume that it will be.
}
+ // Backward compat, use the shared "Set" method instead.
+ public void ScrollTo(double? horizontalOffset, double? verticalOffset, bool disableAnimation)
+ => Set(
+ horizontalOffset: horizontalOffset,
+ verticalOffset: verticalOffset,
+ disableAnimation: disableAnimation);
+
private void TryProcessScrollTo(object sender, object e)
=> TryProcessScrollTo();