Skip to content

Commit 23902c0

Browse files
committed
Add onCompleted/onCancelled call-back to ScrollViewer.SmoothScrollIntoView() and ScrollViewer.ScrollIntoView() extension methods.
1 parent 89a9570 commit 23902c0

File tree

1 file changed

+45
-9
lines changed

1 file changed

+45
-9
lines changed

Application.Avalonia/Controls/ScrollViewerExtensions.cs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static bool IsSmoothScrolling(this ScrollViewer scrollViewer) =>
3737
/// <param name="visual"><see cref="Visual"/> inside <see cref="ScrollViewer"/>.</param>
3838
/// <returns>True if visual has been scrolled into view.</returns>
3939
public static bool ScrollIntoView(this ScrollViewer scrollViewer, Visual visual) =>
40-
ScrollIntoView(scrollViewer, visual, TimeSpan.Zero, null, false);
40+
ScrollIntoView(scrollViewer, visual, TimeSpan.Zero, null, false, null, null);
4141

4242

4343
/// <summary>
@@ -48,11 +48,11 @@ public static bool ScrollIntoView(this ScrollViewer scrollViewer, Visual visual)
4848
/// <param name="scrollToCenter">True to try scrolling <see cref="Visual"/> to center of viewport.</param>
4949
/// <returns>True if visual has been scrolled into view.</returns>
5050
public static bool ScrollIntoView(this ScrollViewer scrollViewer, Visual visual, bool scrollToCenter) =>
51-
ScrollIntoView(scrollViewer, visual, TimeSpan.Zero, null, scrollToCenter);
51+
ScrollIntoView(scrollViewer, visual, TimeSpan.Zero, null, scrollToCenter, null, null);
5252

5353

5454
// Scroll given visual into viewport of ScrollViewer.
55-
static bool ScrollIntoView(ScrollViewer scrollViewer, Visual visual, TimeSpan duration, Func<double, double>? interpolator, bool scrollToCenter)
55+
static bool ScrollIntoView(ScrollViewer scrollViewer, Visual visual, TimeSpan duration, Func<double, double>? interpolator, bool scrollToCenter, Action? onCompleted, Action? onCancelled)
5656
{
5757
// check parameter
5858
if (scrollViewer == visual)
@@ -139,12 +139,12 @@ static bool ScrollIntoView(ScrollViewer scrollViewer, Visual visual, TimeSpan du
139139
});
140140

141141
// scroll to content
142-
return ScrollTo(scrollViewer, new(newOffsetX, newOffsetY), duration, interpolator);
142+
return ScrollTo(scrollViewer, new(newOffsetX, newOffsetY), duration, interpolator, onCompleted, onCancelled);
143143
}
144144

145145

146146
// Scroll to given offset.
147-
static bool ScrollTo(ScrollViewer scrollViewer, Vector offset, TimeSpan duration, Func<double, double>? interpolator)
147+
static bool ScrollTo(ScrollViewer scrollViewer, Vector offset, TimeSpan duration, Func<double, double>? interpolator, Action? onCompleted, Action? onCancelled)
148148
{
149149
// get top level
150150
if (TopLevel.GetTopLevel(scrollViewer) is not { } topLevel)
@@ -187,6 +187,7 @@ void OnPointerWheelChanged(object? sender, RoutedEventArgs e) =>
187187
scrollViewer.RemoveHandler(InputElement.PointerPressedEvent, OnPointerPressed);
188188
scrollViewer.RemoveHandler(InputElement.PointerWheelChangedEvent, OnPointerWheelChanged);
189189
viewportChangedObserverToken.Dispose();
190+
onCancelled?.Invoke();
190191
};
191192
it.Completed += (_, _) =>
192193
{
@@ -199,6 +200,7 @@ void OnPointerWheelChanged(object? sender, RoutedEventArgs e) =>
199200
scrollViewer.RemoveHandler(InputElement.PointerPressedEvent, OnPointerPressed);
200201
scrollViewer.RemoveHandler(InputElement.PointerWheelChangedEvent, OnPointerWheelChanged);
201202
viewportChangedObserverToken.Dispose();
203+
onCompleted?.Invoke();
202204
};
203205
it.Duration = duration;
204206
it.Interpolator = interpolator ?? Interpolators.Default;
@@ -211,7 +213,10 @@ void OnPointerWheelChanged(object? sender, RoutedEventArgs e) =>
211213
animator.Start();
212214
}
213215
else
216+
{
214217
scrollViewer.Offset = new(offsetX, offsetY);
218+
onCompleted?.Invoke();
219+
}
215220
return true;
216221
}
217222

@@ -225,8 +230,24 @@ void OnPointerWheelChanged(object? sender, RoutedEventArgs e) =>
225230
/// <param name="interpolator">Interpolator of smooth scrolling.</param>
226231
/// <param name="scrollToCenter">True to scroll content to center of viewport.</param>
227232
/// <returns>True if smooth scrolling starts successfully.</returns>
228-
public static bool SmoothScrollIntoView(this ScrollViewer scrollViewer, Visual visual, TimeSpan duration, Func<double, double>? interpolator = null, bool scrollToCenter = true) =>
229-
ScrollIntoView(scrollViewer, visual, duration, interpolator, scrollToCenter);
233+
public static bool SmoothScrollIntoView(this ScrollViewer scrollViewer, Visual visual, TimeSpan duration, Func<double, double>? interpolator, bool scrollToCenter) =>
234+
ScrollIntoView(scrollViewer, visual, duration, interpolator, scrollToCenter, null, null);
235+
236+
237+
/// <summary>
238+
/// Scroll given <see cref="Visual"/> smoothly into viewport of <see cref="ScrollViewer"/>.
239+
/// </summary>
240+
/// <param name="scrollViewer"><see cref="ScrollViewer"/>.</param>
241+
/// <param name="visual"><see cref="Visual"/>.</param>
242+
/// <param name="duration">Duration of smooth scrolling.</param>
243+
/// <param name="interpolator">Interpolator of smooth scrolling.</param>
244+
/// <param name="scrollToCenter">True to scroll content to center of viewport.</param>
245+
/// <param name="onCompleted">Function to be called when scrolling completed.</param>
246+
/// <param name="onCancelled">Function to be called when scrolling cancelled.</param>
247+
/// <returns>True if smooth scrolling starts successfully.</returns>
248+
// ReSharper disable once MethodOverloadWithOptionalParameter
249+
public static bool SmoothScrollIntoView(this ScrollViewer scrollViewer, Visual visual, TimeSpan duration, Func<double, double>? interpolator = null, bool scrollToCenter = true, Action? onCompleted = null, Action? onCancelled = null) =>
250+
ScrollIntoView(scrollViewer, visual, duration, interpolator, scrollToCenter, onCompleted, onCancelled);
230251

231252

232253
/// <summary>
@@ -237,8 +258,23 @@ public static bool SmoothScrollIntoView(this ScrollViewer scrollViewer, Visual v
237258
/// <param name="duration">Duration of smooth scrolling.</param>
238259
/// <param name="interpolator">Interpolator of smooth scrolling.</param>
239260
/// <returns>True if smooth scrolling starts successfully.</returns>
240-
public static bool SmoothScrollTo(this ScrollViewer scrollViewer, Vector offset, TimeSpan duration, Func<double, double>? interpolator = null) =>
241-
ScrollTo(scrollViewer, offset, duration, interpolator);
261+
public static bool SmoothScrollTo(this ScrollViewer scrollViewer, Vector offset, TimeSpan duration, Func<double, double>? interpolator) =>
262+
ScrollTo(scrollViewer, offset, duration, interpolator, null, null);
263+
264+
265+
/// <summary>
266+
/// Scroll <see cref="ScrollViewer"/> to given offset smoothly.
267+
/// </summary>
268+
/// <param name="scrollViewer"><see cref="ScrollViewer"/>.</param>
269+
/// <param name="offset">Target offset.</param>
270+
/// <param name="duration">Duration of smooth scrolling.</param>
271+
/// <param name="interpolator">Interpolator of smooth scrolling.</param>
272+
/// <param name="onCompleted">Function to be called when scrolling completed.</param>
273+
/// <param name="onCancelled">Function to be called when scrolling cancelled.</param>
274+
/// <returns>True if smooth scrolling starts successfully.</returns>
275+
// ReSharper disable once MethodOverloadWithOptionalParameter
276+
public static bool SmoothScrollTo(this ScrollViewer scrollViewer, Vector offset, TimeSpan duration, Func<double, double>? interpolator = null, Action? onCompleted = null, Action? onCancelled = null) =>
277+
ScrollTo(scrollViewer, offset, duration, interpolator, onCompleted, onCancelled);
242278

243279

244280
/// <summary>

0 commit comments

Comments
 (0)