BnScroll
Namespace: BlazorNative.Components
A scrolling viewport. Renders as a native ScrollView on Android and a
UIScrollView on iOS. It is a flex item
(BnLayoutItem.Grow, BnLayoutItem.Shrink,
BnLayoutItem.Basis, BnLayoutItem.AlignSelf, the
box, BnLayoutItem.Margin, BnLayoutItem.Position)
that scrolls its content.
public sealed class BnScroll : BnLayoutItem, Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleEvent, Microsoft.AspNetCore.Components.IHandleAfterRender
Inheritance Object → ComponentBase → BnLayoutItem → BnScroll
Implements IComponent, IHandleEvent, IHandleAfterRender
Attributes NullableContextAttribute, NullableAttribute
Remarks:
Not a flex container. There is no Direction, Justify,
Align, Wrap, Gap or Padding parameter: those
would style the viewport itself rather than the content inside it — they
would space nothing, or push the content to a negative offset a scroll view
can never scroll back to. To lay out the content, put a
BnColumn inside: <BnScroll Height="200"><BnColumn Gap="8">…</BnColumn></BnScroll>. Both platforms ignore
those style names on a scroll node, so there is no way around it.
Vertical only. Horizontal scrolling is a different widget class on Android, and is not supported rather than half-supported.
Give it a definite height. An auto-height BnScroll takes
its height from its content, so the viewport equals the content and
nothing scrolls; the shells log one warning when that happens. Use an explicit
BnLayoutItem.Height, or — inside a parent with a definite
height — Grow="1" Basis="0" (CSS's flex: 1).
alone is not enough, and it is the
mistake everybody makes here. With BnLayoutItem.Basis left at
auto, the scroll node's flex basis is its content's height,
so the free space against a shorter parent is negative — and
BnLayoutItem.Grow only distributes positive free
space. The negative goes to the shrink pass, and Yoga's
BnLayoutItem.Shrink default is 0, so nothing shrinks:
the viewport keeps its content's full height, overflows its parent, and does
not scroll. Basis="0" (or Shrink="1") is what fixes it — which
is exactly why CSS's flex: 1 shorthand sets the basis to 0.
Your children are re-parented into a content node inside the viewport, whose height is the total content height — that is what the platform scrolls.
Properties
OnScroll
Raised with the vertical content offset, in dp on Android and pt on iOS, as the viewport scrolls. Optional: nothing is attached to the native control unless you supply a handler.
Events are conflated, not queued — at most one per rendered frame, latest offset wins. A slow handler therefore sees fewer, fresher events rather than a growing backlog, so you cannot use this to count scroll ticks.
The offset arrives raw. iOS rubber-banding can report a negative offset, or one past the end of the scroll range. Clamp it if your maths depends on it being inside the content.
public EventCallback<BnScrollEventArgs> OnScroll { get; set; }
Property Value
EventCallback<BnScrollEventArgs>
AutoScrollToEnd
Scroll to the end of the content on every render, for append-driven views — a log tail, a chat transcript, console output — where new content arriving below the fold should bring itself into view. Default false.
Every render, not every append. This component cannot see that your content grew; it only knows it re-rendered. So a re-render for an unrelated reason also scrolls to the end. That is usually what a view with this switched on wants, but it is why it is a parameter you choose rather than a default — if you need "only when items were added", call BnScroll.ScrollToEndAsync() yourself at the point you add them.
public bool AutoScrollToEnd { get; set; }
Property Value
ChildContent
The content to scroll. Wrap it in a BnColumn to give it a gap, a padding or an alignment — this component will not do that for you.
public RenderFragment? ChildContent { get; set; }
Property Value
BackgroundColor
Fill colour behind the component. Null leaves it transparent.
public string? BackgroundColor { get; set; }
Property Value
Margin
Space outside the component, between it and its siblings. Null = none.
public BnAutoLength? Margin { get; set; }
Property Value
Remarks:
auto is legal here and absorbs free space, which re-centres the node.
AlignSelf
Cross-axis alignment for this item alone, overriding the parent's. Null = inherit.
public FlexAlign? AlignSelf { get; set; }
Property Value
Grow
Share of leftover space this item takes (unitless ratio). Null = Yoga's default (0).
public float? Grow { get; set; }
Property Value
Shrink
Share of overflow this item gives up (unitless ratio). Null = Yoga's default (1).
public float? Shrink { get; set; }
Property Value
Basis
Starting main-axis size before grow/shrink. Null = auto.
public BnAutoLength? Basis { get; set; }
Property Value
Width
Box width. Null = auto.
public BnAutoLength? Width { get; set; }
Property Value
Height
Box height. Null = auto.
public BnAutoLength? Height { get; set; }
Property Value
MinWidth
Lower bound on width. Null = unset.
public BnLength? MinWidth { get; set; }
Property Value
MaxWidth
Upper bound on width. Null = unset.
public BnLength? MaxWidth { get; set; }
Property Value
MinHeight
Lower bound on height. Null = unset.
public BnLength? MinHeight { get; set; }
Property Value
MaxHeight
Upper bound on height. Null = unset.
public BnLength? MaxHeight { get; set; }
Property Value
Position
Positioning scheme. Null = Yoga's default (relative).
public FlexPosition? Position { get; set; }
Property Value
Top
Top inset. Null = unset.
public BnLength? Top { get; set; }
Property Value
Right
Right inset. Null = unset.
public BnLength? Right { get; set; }
Property Value
Bottom
Bottom inset. Null = unset.
public BnLength? Bottom { get; set; }
Property Value
Left
Left inset. Null = unset.
public BnLength? Left { get; set; }
Property Value
Constructors
BnScroll()
public BnScroll()
Methods
ScrollToAsync(Single)
Scrolls to offset — dp on Android, pt on iOS,
the same units BnScroll.OnScroll reports. An offset outside the
content is clamped by the platform, not rejected here.
public ValueTask ScrollToAsync(float offset)
Parameters
offset Single
The vertical content offset to scroll to.
Returns
ValueTask
A task that completes when the command has been QUEUED for the
next frame — not when the view has finished moving. Use
BnScroll.OnScroll to observe where it actually landed.
ScrollToEndAsync()
Scrolls to the end of the content.
public ValueTask ScrollToEndAsync()
Returns
ValueTask
A task that completes when the command has been QUEUED for the
next frame — not when the view has finished moving.
Remarks:
The end is computed by the shell, not here: content height is a layout result the platform holds, so an offset computed on this side would be one frame stale — exactly wrong for the append-driven case this exists to serve.