Class ScrollViewer
Clips Content to this control's bounds and lets it be scrolled within that viewport via HorizontalOffset/VerticalOffset - settable directly, or driven by the mouse wheel/touch-swipe (see IScrollEvents).
public class ScrollViewer : ContentControl, INotifyPropertyChanging, IBindingTarget, INotifyPropertyChanged, INotifyFocusChanged, IContainerLayout
- Inheritance
-
ScrollViewer
- Implements
- Inherited Members
- Extension Methods
Remarks
No visible scrollbar thumbs are drawn in v1 - this is purely the viewport/offset/clipping model. A visual scrollbar can be layered on top later using ExtentWidth/ExtentHeight/ ViewportWidth/ViewportHeight to size a thumb.
Constructors
ScrollViewer()
Initializes a new instance of the ScrollViewer class.
public ScrollViewer()
Properties
ExtentHeight
Gets Content's full natural height, regardless of how much of it is currently visible - or, when Content implements IVirtualizingScrollInfo, its own reported estimate instead of a full measure.
public float ExtentHeight { get; }
Property Value
Remarks
While VerticalScrollMode is Disabled, the extent is capped at ViewportHeight, so there is nothing to scroll vertically.
ExtentWidth
Gets Content's full natural width, regardless of how much of it is currently visible - or, when Content implements IVirtualizingScrollInfo, its own reported estimate instead of a full measure.
public float ExtentWidth { get; }
Property Value
Remarks
While HorizontalScrollMode is Disabled, the extent is capped at ViewportWidth, so there is nothing to scroll horizontally.
HorizontalOffset
Gets or sets how far Content is scrolled horizontally, clamped to
[0, ExtentWidth - ViewportWidth].
[BindingOverride(BindingMode.TwoWay)]
public float HorizontalOffset { get; set; }
Property Value
HorizontalScrollMode
public ScrollMode HorizontalScrollMode { get; set; }
Property Value
Remarks
- Enabled: the content keeps its natural width, which can be wider than the viewport.
-
Disabled: the content is laid out at most as wide as the viewport, and
HorizontalOffset stays at
0. Use it for pages that should only scroll vertically, so a long line of text can't widen the whole page.
PanningDeceleration
Gets or sets how quickly a fling slows down, in this control's units per second squared. Defaults to 1500;
0 disables inertia.
public float PanningDeceleration { get; set; }
Property Value
Exceptions
- ArgumentOutOfRangeException
The value is negative or not finite.
PanningMode
Gets or sets the axes this ScrollViewer pans along with touch and the middle mouse button. Defaults to Auto.
public PanningMode PanningMode { get; set; }
Property Value
Remarks
A pan claims a drag only along axes where the content can still move in the drag's direction, so a list that is already at its edge lets the gesture reach the next scroll area out. The left mouse button never pans.
VerticalOffset
Gets or sets how far Content is scrolled vertically, clamped to
[0, ExtentHeight - ViewportHeight].
[BindingOverride(BindingMode.TwoWay)]
public float VerticalOffset { get; set; }
Property Value
VerticalScrollMode
public ScrollMode VerticalScrollMode { get; set; }
Property Value
Remarks
- Enabled: the content keeps its natural height, which can be taller than the viewport.
-
Disabled: the content is laid out at most as tall as the viewport, and
VerticalOffset stays at
0. Use it for content that should only scroll horizontally.
ViewportHeight
Gets the visible viewport's height, i.e. this control's ContentBounds height (already inset by BorderThickness and Padding).
public float ViewportHeight { get; }
Property Value
ViewportWidth
Gets the visible viewport's width, i.e. this control's ContentBounds width (already inset by BorderThickness and Padding).
public float ViewportWidth { get; }
Property Value
Methods
ArrangeContent()
Handles custom arrange logic when overridden in any UIElement instance.
protected override void ArrangeContent()
Remarks
This method is called during the arrange pass to position and size the element's content within its final bounds. The element's position and size are already determined by the layout system and available in the ActualBounds property.
When implementing this method:
- Position child elements within the available space;
- Respect the element's padding when positioning content;
- Handle any content-specific layout requirements;
- Call Arrange() on child elements if needed.
CanHitTestChildren()
Gets a value indicating whether HitTest(Vector2) descends into this element's children.
protected override bool CanHitTestChildren()
Returns
- bool
true by default. Returning false makes the element itself the hit target for every point inside it - e.g. a scrolling list during a fling, so the press that stops it doesn't reach an item.
GetDragAxes(in DragClaimContext)
Returns the axes along which this element wants to own a drag that starts on it or a descendant.
protected override DragAxes GetDragAxes(in DragClaimContext context)
Parameters
contextDragClaimContextThe starting drag.
Returns
Remarks
When a drag starts, Canvas asks the hit element and each ancestor in turn. The innermost element whose answer contains the drag's main axis (the larger component of LocalDirection) owns the gesture. If none does, the innermost element with any answer owns it. Only the owner receives OnDragStarted(Point), OnDragPerforming(Point), OnDragFling(Vector2) and OnDragEnded(Point).
An element that handles drags must override this method: overriding OnDragStarted(Point) alone receives nothing.
OnDetached()
Raises the Detached event.
protected override void OnDetached()
Remarks
Propagates null to every element in GetVisualChildren(), mirroring OnAttached() - see its remarks.
OnDragEnded(Point)
Invoked by Canvas when a drag sequence owned by this element (see GetDragAxes(in DragClaimContext)) has ended - released or canceled. The base implementation does nothing.
protected override void OnDragEnded(Point screenPoint)
Parameters
screenPointPointThe drag's ending position, in screen/window space.
OnDragFling(Vector2)
Invoked by Canvas on the owner of a drag that completed (was released), right before OnDragEnded(Point). It isn't invoked when the drag is canceled. The base implementation does nothing.
protected override void OnDragFling(Vector2 screenVelocity)
Parameters
screenVelocityVector2The release velocity, in physical pixels per second.
OnDragPerforming(Point)
Invoked by Canvas whenever the pointer moves during a drag sequence owned by this element (see GetDragAxes(in DragClaimContext)). The base implementation does nothing.
protected override void OnDragPerforming(Point screenPoint)
Parameters
screenPointPointThe drag's current position, in screen/window space.
OnDragStarted(Point)
Invoked by Canvas when a drag sequence starts and this element owns it (see GetDragAxes(in DragClaimContext); overriding this method alone receives nothing). The base implementation does nothing.
protected override void OnDragStarted(Point screenPoint)
Parameters
screenPointPointThe drag's starting position, in screen/window space.
OnScroll(ScrollInfo)
Invoked by Canvas when the mouse wheel/touch-swipe scrolls (see Scroll) while this element (or a descendant) is hovered. The base implementation does nothing and returns false.
protected override bool OnScroll(ScrollInfo info)
Parameters
infoScrollInfoThe scroll delta and axis.
Returns
- bool
true if this element actually consumed the scroll (e.g. a
ScrollViewerthat had room left to scroll further ininfo's direction) - Canvas stops dispatching to further ancestors once an element returns true, so one nested scrollable region doesn't also scroll every scrollable ancestor around it. Returning false (e.g. already scrolled to the limit in that direction) lets the event bubble up to an outer scrollable ancestor, which is what makes "overscroll" naturally hand off to it.
StopInertia()
Stops a running fling immediately, leaving the offsets where they are.
public void StopInertia()
Events
ScrollChanged
Occurs when HorizontalOffset or VerticalOffset changes.
public event EventHandler? ScrollChanged