ScrollBarBase
The drawn, themeable scroll bar that VerticalScrollBar and HorizontalScrollBar
are built on: range, position, line and page steps, colours and custom renderers in one place.
public abstract partial class ScrollBarBase : Control
Inherits from / implements: Control
Remarks
What it is for
Use a VerticalScrollBar or a HorizontalScrollBar wherever a form needs a
scroll bar that matches its theme – beside a custom-drawn view, a long preview, a timeline – or let a
host such as the suite's scrolling panel and scrollable picture box create and dock them for you. This
class cannot be created directly; it holds everything the two orientations share.
The range model
The range runs from MinimumScrollRange (0) to MaximumScrollRange, in
whatever units the application scrolls in – pixels of a picture, rows of a report. LargeChange
is how much of that range is in view at once: it sets the thumb's length (the track length times
LargeChange over the range, never less than 6 pixels) and one page step.
Position is the first unit in view, so it runs from 0 to
MaximumScrollRange minus LargeChange; values outside are clamped.
SmallChange is one arrow click, arrow key or wheel notch.
Knowing when it scrolled
PositionChanged– every change ofPosition, whatever caused it. The one to use for keeping a view in step.- The orientation's own line, page and thumb events (
LineUp,PageDown,ThumbLeft...) – raised for mouse actions on the arrows, the track and the thumb. - The orientation's
Scrollevent – the same mouse actions in the framework'sScrollEventArgsform, for code written against the standard scroll bar.
The keyboard (arrow keys, and Page Up / Page Down on the vertical bar) and the mouse wheel change
Position directly, so they raise PositionChanged only.
Appearance
Colours, images and the auto-repeat rate live on ScrollBarRenderingConfigurator; pick a
ColorTheme there and adjust individual colours after it. To draw a part entirely yourself,
assign ScrollBarTrackRenderer, ScrollBarThumbRenderer,
ScrollBarThumbGripperRenderer or ScrollBarNavigationButtonRenderer.
Thickness is in device pixels
Unlike the suite's other metrics, VerticalScrollBarWidth and
HorizontalScrollBarHeight are device pixels. Left alone, they follow the system scroll bar
size for the display the bar is on (17 at 96 DPI) and follow the window to a display at another scale; a
value you assign is used as given, on every display.
Examples
A themed vertical bar scrolling a tall invoice page inside a fixed viewport.
using Binarymission.WinForms.Controls.ScrollBars;
var viewport = new Panel { Location = new Point(12, 12), Size = new Size(420, 300) };
var invoicePage = new Panel { Size = new Size(420, 1200), BackColor = Color.White };
viewport.Controls.Add(invoicePage);
var pageBar = new VerticalScrollBar
{
Location = new Point(436, 12),
Height = 300,
MaximumScrollRange = 1200, // the page's height, in pixels
LargeChange = 300, // the part of it the viewport shows
SmallChange = 40,
};
pageBar.ScrollBarRenderingConfigurator.ColorTheme = ColorTheme.OfficeBlue;
// One handler covers arrows, track, thumb, keyboard and wheel.
pageBar.PositionChanged += (sender, e) => invoicePage.Top = -(int)e.NewPosition;
Controls.Add(viewport);
Controls.Add(pageBar);See also
Members at a glance
| Constructors | |
|---|---|
ScrollBarBase | Initialises a stand-alone scroll bar with a range of 0 to 100, a small change of 10 and a large change of 20, sized from the system scroll bar metric. |
ScrollBarBase | Initialises a scroll bar owned by a host control, which it serves and docks into. |
| Properties | |
EarlierScrollPosition | Gets the position the bar held before its latest move. |
HorizontalScrollBarHeight | Gets or sets the thickness of a horizontal bar: its height, and the size of its square arrow buttons. |
IsDrawingCustomThumbImage | Gets or sets whether the thumb was last drawn from one of the configurator's thumb images. |
LargeChange | Gets or sets how much of the range is in view at once: one page step, and the thumb's share of the track. |
MaximumScrollRange | Gets or sets the high end of the range: the total extent being scrolled, in the application's units. |
MinimumScrollRange | Gets or sets the low end of the range. |
PaddingGap | Gets or sets the gap left between a self-positioning bar and the edges of the control it serves. |
Position | Gets or sets where the view is in the range: the first unit of the range in view. |
ScrollBarNavigationButtonRenderer | Gets or sets an object that draws the two arrow buttons, background and arrow, in place of the built-in look. |
ScrollBarRenderingConfigurator | Gets or sets the colours, images, theme and auto-repeat rate the bar is drawn and driven with. |
ScrollBarThumbGripperRenderer | Gets or sets an object that draws the grip marks on the thumb in place of the built-in ridges. |
ScrollBarThumbRenderer | Gets or sets an object that draws the thumb in place of the built-in fill, image and border. |
ScrollBarTrackRenderer | Gets or sets an object that draws the track – the background behind the arrows and the thumb – in place of the built-in fill. |
ScrollServiceTargetControl | Gets or sets the control the bar serves: the one it sizes itself against and, when its window is created, is placed inside. |
ShouldAutomaticallyPositionScroller | Gets or sets whether the bar docks itself to the edge of the control it serves and sizes itself to it. |
SmallChange | Gets or sets how far one arrow click, arrow key or wheel notch moves Position. |
VerticalScrollBarWidth | Gets or sets the thickness of a vertical bar: its width, and the size of its square arrow buttons. |
| Methods | |
Dispose | Releases the bar: it stops listening to the control it serves and to its host, and disposes the corner square it placed in the host. |
DrawScrollNavigator | Draws one arrow button: through ScrollBarNavigationButtonRenderer when one is set,
otherwise with the configurator's button colours and its arrow image or drawn arrow for the state. |
DrawThumbArtefactConditional | Draws the thumb at GetThumbArtefactRectangle: through ScrollBarThumbRenderer
when one is set, otherwise from the configurator's thumb image for the state, its thumb gradient, or
its solid thumb colour. |
GetThumbArtefactRectangle | Returns the thumb's bounds, in client coordinates. The base returns Rectangle.Empty; each
orientation overrides it. |
IsInputKey | Claims the arrow keys and Page Up / Page Down, so they reach the bar rather than moving the focus. |
OnDpiChangedAfterParent | Raises DpiChangedAfterParent and, unless the thickness was set in code, re-reads the system scroll
bar size for the new display and lays the bar out again. |
OnHandleCreated | Raises Control.HandleCreated, places the bar's window inside
ScrollServiceTargetControl, reads the system thickness for that display and lays the bar out. |
OnKeyDown | Raises Control.KeyDown, then moves the position: Up and Down (vertical bar) and Left and
Right (horizontal bar) by SmallChange, Page Up and Page Down (vertical bar) by
LargeChange. |
OnKeyUp | Raises Control.KeyUp. The bar does nothing more on a key release. |
OnMouseWheel | Raises Control.MouseWheel, then moves the position by SmallChange for the
notch: on a vertical bar always, on a horizontal bar only while Shift is held. |
OnPaint | Raises Control.Paint and then draws the bar through PaintScrollBar. |
OnParentChanged | Raises Control.ParentChanged and attaches the bar to its new parent. A stand-alone bar
takes the parent as its ScrollServiceTargetControl; a bar created by a host stays with
the host. |
OnTabStopChanged | Raises Control.TabStopChanged and makes the bar focusable, or not, to match
Control.TabStop. |
PaintBackground | Draws the track over the whole client area: through ScrollBarTrackRenderer when one is
set, otherwise as the configurator's track gradient, or TrackFillColor when either gradient colour
is Color.Empty. |
PaintScrollBar | Draws the whole bar. The base does nothing; each orientation overrides it and calls the drawing helpers in its own order. |
PerformSizeRefresh | Lays the bar out again against ScrollServiceTargetControl. The base does nothing; each
orientation overrides it. |
RaisePositionChanged | Raises PositionChanged. |
WndProc | Processes the bar's window messages, ending any auto-repeat when the left button comes up. Messages for a window that no longer exists are dropped. |
| Events | |
HorizontalScrollBarHeightChanged | Occurs when HorizontalScrollBarHeight is set in code. |
PositionChanged | Occurs when Position changes, whatever moved it: the arrows, the track, the thumb, the
keyboard, the wheel or code. |
VerticalScrollBarWidthChanged | Occurs when VerticalScrollBarWidth is set in code. |
| Fields | |
_earlierScrolledPosition | The backing field of EarlierScrollPosition: the position before the latest move. |
_executeNavigationEvent | Set while the thumb's geometry pulls Position back inside the range, so that the
correction is reported through the line events. |
_gripperArtefactHeight | The extent, in device pixels, of the grip ridges drawn across a horizontal thumb: the bar's height less a small margin. For derived scroll bars that draw their own gripper. |
_gripperArtefactWidth | The extent, in device pixels, of the grip ridges drawn across a vertical thumb: the bar's width less a small margin. For derived scroll bars that draw their own gripper. |
_largeChange | The backing field of LargeChange. |
_maximumScrollRange | The backing field of MaximumScrollRange. |
_minimumScrollRange | The backing field of MinimumScrollRange. |
_parentInstanceUsingThisScrollerInstance | The host control passed to the constructor through IScrollersDockHost.DockHost, or
null for a stand-alone bar. |
_performCarefulSizing | Set when a vertical and a horizontal bar serve the same control, so that each leaves room for the other and for the corner square between them. |
_scrollPosition | The backing field of Position. A double, so that a long range still moves
smoothly over a short track. |
_scrollServiceTargetControl | The control the bar sizes and docks itself against – the backing field of
ScrollServiceTargetControl. |
_shouldAutoScrolingActionEnd | Set to end the auto-repeat loop that runs while an arrow or the track is held down; the bar sets it when the left button comes up. |
_smallChange | The backing field of SmallChange. |
_usingSibling | Not used by the library. Kept because it is part of the protected surface. |
Constructors
ScrollBarBase
Initialises a stand-alone scroll bar with a range of 0 to 100, a small change of 10 and a large change of 20, sized from the system scroll bar metric.
ScrollBarBase
Initialises a scroll bar owned by a host control, which it serves and docks into.
Parameters
parentInstanceUsingThisScrollerInstance- The host. Its
IScrollersDockHost.DockHostbecomesScrollServiceTargetControl. Must not benull.
Properties
EarlierScrollPosition
Gets the position the bar held before its latest move.
- Value
- The previous
Position; 0 until the bar has moved. After a request that changed nothing it equalsPosition.
Remarks
Handy in a line, page or thumb event handler, which carries no positions of its own:
Position - EarlierScrollPosition is how far the view has to move.
HorizontalScrollBarHeight
Gets or sets the thickness of a horizontal bar: its height, and the size of its square arrow buttons.
- Value
- In device pixels, not logical ones. By default the system's horizontal scroll bar height for the display the bar is on – 17 at 96 DPI, 34 at 192 DPI.
Remarks
This is the one metric in the suite that is not in logical pixels. Until it is assigned, the bar reads the system metric for the display it is shown on, and reads it again when the window moves to a display at another scale. Once assigned, the value is used as given on every display, and the system metric is not consulted again.
The bar's own Control.Height is kept equal to this value. Assigning it raises
HorizontalScrollBarHeightChanged.
On a VerticalScrollBar this property is hidden: it returns
VerticalScrollBarWidth and ignores assignments.
See also
IsDrawingCustomThumbImage
Gets or sets whether the thumb was last drawn from one of the configurator's thumb images.
- Value
truewhile a thumb image is in use, in which case the gripper is not drawn over it. Set by the built-in thumb drawing; the default isfalse.
LargeChange
Gets or sets how much of the range is in view at once: one page step, and the thumb's share of the track.
- Value
- In range units. The default is 20.
- Default
20
Remarks
A track click (or Page Up / Page Down on a vertical bar) moves Position by this much, the thumb is this
fraction of the track long, and Position stops at MaximumScrollRange minus this
value. For a viewport, set it to the viewport's size in range units.
A value below MinimumScrollRange or above MaximumScrollRange is stored as
1, so set MaximumScrollRange first.
See also
MaximumScrollRange
Gets or sets the high end of the range: the total extent being scrolled, in the application's units.
- Value
- The default is 100.
- Default
100
Remarks
For a viewport, set it to the content's full size and LargeChange to the visible part.
Set it before LargeChange and SmallChange, which are checked against it.
A value below MinimumScrollRange is ignored.
MinimumScrollRange
Gets or sets the low end of the range.
- Value
- 0, which is also the default.
- Default
0
Remarks
The setter accepts a new value only while the current one is above zero, which the default is
not, so in practice the range always starts at 0. Position is clamped at 0 in any case.
PaddingGap
Gets or sets the gap left between a self-positioning bar and the edges of the control it serves.
- Value
- In pixels, not scaled with the display. The default is 0.
Remarks
Used only while ShouldAutomaticallyPositionScroller is true, and read
when the bar is next laid out (when the served control is resized).
Position
Gets or sets where the view is in the range: the first unit of the range in view.
- Value
- From 0 to
MaximumScrollRangeminusLargeChange. The default is 0. - Default
0
Remarks
A value below 0 is stored as 0, and a value at or beyond the top of the range as
MaximumScrollRange minus LargeChange, so assigning
MaximumScrollRange to it scrolls to the end.
A change raises PositionChanged and repaints the bar. Setting the position in code
does not raise the line, page or Scroll events.
Example
// Bring row 250 of the report to the top of the view, 18 pixels per row.
reportBar.Position = 250 * 18;See also
ScrollBarRenderingConfigurator
Gets or sets the colours, images, theme and auto-repeat rate the bar is drawn and driven with.
- Value
- The bar's configurator. Each bar is created with its own, set to the
ColorTheme.GradientBrowntheme; it is nevernullunless you assignnull.
Remarks
Expandable in the property grid and serialised with the form. The bar reads it every time it paints,
so a change shows at the next repaint; call Control.Invalidate to see it at once.
Two bars that should look alike need the same settings on both configurators, or the same configurator instance assigned to both.
Example
var look = timelineBar.ScrollBarRenderingConfigurator;
look.ColorTheme = ColorTheme.OfficeSilver; // first: a theme overwrites the colours below
look.GripperColor1 = Color.DimGray; // the grip ridges
look.GripperColor2 = Color.WhiteSmoke;
look.AutoScrollInterval = 60; // faster repeat while an arrow is held
timelineBar.Invalidate();See also
ScrollBarThumbGripperRenderer
Gets or sets an object that draws the grip marks on the thumb in place of the built-in ridges.
- Value
- Your renderer, or
null(the default) for the built-in gripper.
Remarks
Called only when ScrollBarRenderingConfigurator.ShouldDrawGripperArtefact
is true, the thumb is not drawn from an image, and the thumb is at least 12 logical
pixels long. It is handed the thumb's bounds and its visual state.
See also
ScrollBarThumbRenderer
Gets or sets an object that draws the thumb in place of the built-in fill, image and border.
- Value
- Your renderer, or
null(the default) for the built-in thumb.
Remarks
The renderer is handed the thumb's bounds and whether it is idle, hot or pressed. The gripper is drawn
over it afterwards unless ScrollBarRenderingConfigurator.ShouldDrawGripperArtefact
is false.
See also
ScrollBarTrackRenderer
Gets or sets an object that draws the track – the background behind the arrows and the thumb – in place of the built-in fill.
- Value
- Your renderer, or
null(the default) for the built-in track.
Remarks
The renderer is handed the bar's whole client area; the arrows and the thumb are drawn over it.
See also
ScrollServiceTargetControl
Gets or sets the control the bar serves: the one it sizes itself against and, when its window is created, is placed inside.
- Value
- The served control. It is set to the bar's parent when the bar is added to one, and to the host for a bar created by a host. Not serialised by the designer.
Remarks
The bar listens to this control's Control.SizeChanged to keep its own size in step, and
reads the display scale from it for the system thickness.
See also
ShouldAutomaticallyPositionScroller
Gets or sets whether the bar docks itself to the edge of the control it serves and sizes itself to it.
- Value
trueto dock a vertical bar to the right edge and a horizontal bar to the bottom edge;false(the default) to leave the bar where it was placed.
Remarks
While on, the bar follows the size of ScrollServiceTargetControl: it is inset by
PaddingGap, and when a vertical and a horizontal bar serve the same control each leaves room
for the other. The suite's scrolling panel and scrollable picture box turn this on for the bars they
host.
While off, the bar keeps its location and length and only its thickness is set, from
VerticalScrollBarWidth or HorizontalScrollBarHeight.
See also
SmallChange
Gets or sets how far one arrow click, arrow key or wheel notch moves Position.
- Value
- In range units. The default is 10.
- Default
10
Remarks
A value below MinimumScrollRange or above MaximumScrollRange is stored as
1, so set MaximumScrollRange first.
See also
VerticalScrollBarWidth
Gets or sets the thickness of a vertical bar: its width, and the size of its square arrow buttons.
- Value
- In device pixels, not logical ones. By default the system's vertical scroll bar width for the display the bar is on – 17 at 96 DPI, 34 at 192 DPI.
Remarks
This is the one metric in the suite that is not in logical pixels. Until it is assigned, the bar reads the system metric for the display it is shown on, and reads it again when the window moves to a display at another scale. Once assigned, the value is used as given on every display, and the system metric is not consulted again – so a width persisted by the designer stays that many device pixels at any scale.
The bar's own Control.Width is kept equal to this value. Assigning it raises
VerticalScrollBarWidthChanged.
On a HorizontalScrollBar this property is hidden: it returns
HorizontalScrollBarHeight and ignores assignments.
See also
Methods
Dispose
Releases the bar: it stops listening to the control it serves and to its host, and disposes the corner square it placed in the host.
Parameters
disposingtruewhen called fromDispose().
DrawThumbArtefactConditional
Draws the thumb at GetThumbArtefactRectangle: through ScrollBarThumbRenderer
when one is set, otherwise from the configurator's thumb image for the state, its thumb gradient, or
its solid thumb colour.
Parameters
graphicsInstance- The surface to draw on.
controlVisualState- Whether the thumb is idle, under the pointer or being dragged.
GetThumbArtefactRectangle
Returns the thumb's bounds, in client coordinates. The base returns Rectangle.Empty; each
orientation overrides it.
Returns
The thumb's bounds.
Remarks
The same rectangle is used for drawing and for hit testing, so an override moves both.
IsInputKey
Claims the arrow keys and Page Up / Page Down, so they reach the bar rather than moving the focus.
Parameters
keyData- The key being tested.
Returns
true for Up, Down, Left, Right, Page Up and Page Down; otherwise the base
answer.
OnDpiChangedAfterParent
Raises DpiChangedAfterParent and, unless the thickness was set in code, re-reads the system scroll
bar size for the new display and lays the bar out again.
Parameters
e- The event data.
OnHandleCreated
Raises Control.HandleCreated, places the bar's window inside
ScrollServiceTargetControl, reads the system thickness for that display and lays the bar out.
Parameters
e- The event data.
OnKeyDown
Raises Control.KeyDown, then moves the position: Up and Down (vertical bar) and Left and
Right (horizontal bar) by SmallChange, Page Up and Page Down (vertical bar) by
LargeChange.
Parameters
e- The key data.
Remarks
The move raises PositionChanged, not the line, page or Scroll events.
OnKeyUp
Raises Control.KeyUp. The bar does nothing more on a key release.
Parameters
e- The key data.
OnMouseWheel
Raises Control.MouseWheel, then moves the position by SmallChange for the
notch: on a vertical bar always, on a horizontal bar only while Shift is held.
Parameters
e- The wheel data. A notch away from the user scrolls back, towards 0.
Remarks
The notch is marked handled, so a form or panel that also scrolls on the wheel does not move as well.
The move raises PositionChanged, not the line or Scroll events.
OnPaint
Raises Control.Paint and then draws the bar through PaintScrollBar.
Parameters
e- The paint data.
OnParentChanged
Raises Control.ParentChanged and attaches the bar to its new parent. A stand-alone bar
takes the parent as its ScrollServiceTargetControl; a bar created by a host stays with
the host.
Parameters
e- The event data.
OnTabStopChanged
Raises Control.TabStopChanged and makes the bar focusable, or not, to match
Control.TabStop.
Parameters
e- The event data.
PaintBackground
Draws the track over the whole client area: through ScrollBarTrackRenderer when one is
set, otherwise as the configurator's track gradient, or TrackFillColor when either gradient colour
is Color.Empty.
Parameters
g- The surface to draw on.
PaintScrollBar
Draws the whole bar. The base does nothing; each orientation overrides it and calls the drawing helpers in its own order.
Parameters
g- The surface to draw on.
Remarks
Override in a derived bar to draw over the finished bar – the marker scroll bars draw their marks this way, after calling the base.
PerformSizeRefresh
Lays the bar out again against ScrollServiceTargetControl. The base does nothing; each
orientation overrides it.
Remarks
Called when the served control is resized, when the thickness changes and when the window is created.
RaisePositionChanged
Raises PositionChanged.
Parameters
oldPosition- The position before the change.
newPosition- The position after it.
WndProc
Processes the bar's window messages, ending any auto-repeat when the left button comes up. Messages for a window that no longer exists are dropped.
Parameters
m- The message.
Events
HorizontalScrollBarHeightChanged
Occurs when HorizontalScrollBarHeight is set in code.
Remarks
Raised on every assignment, before the new height is applied – read the value you assigned, not the property, in the handler. Not raised when the height follows the system metric.
PositionChanged
Occurs when Position changes, whatever moved it: the arrows, the track, the thumb, the
keyboard, the wheel or code.
Remarks
Raised once per actual change, after the new position is stored; setting the current value again raises nothing. While the thumb is dragged it is raised for every step, so keep the handler quick.
It runs inside the bar's mouse handling – while an arrow is held, inside its auto-repeat loop – so do not show a dialog box from it.
Example
timelineBar.PositionChanged += (sender, e) =>
{
timelineView.FirstVisibleDay = startDate.AddDays(e.NewPosition);
timelineView.Invalidate();
};See also
VerticalScrollBarWidthChanged
Occurs when VerticalScrollBarWidth is set in code.
Remarks
Raised on every assignment, before the new width is applied – read the value you assigned, not the property, in the handler. Not raised when the width follows the system metric.
Fields
_earlierScrolledPosition
The backing field of EarlierScrollPosition: the position before the latest move.
_gripperArtefactHeight
The extent, in device pixels, of the grip ridges drawn across a horizontal thumb: the bar's height less a small margin. For derived scroll bars that draw their own gripper.
_gripperArtefactWidth
The extent, in device pixels, of the grip ridges drawn across a vertical thumb: the bar's width less a small margin. For derived scroll bars that draw their own gripper.
_parentInstanceUsingThisScrollerInstance
The host control passed to the constructor through IScrollersDockHost.DockHost, or
null for a stand-alone bar.
_performCarefulSizing
Set when a vertical and a horizontal bar serve the same control, so that each leaves room for the other and for the corner square between them.
_scrollPosition
The backing field of Position. A double, so that a long range still moves
smoothly over a short track.
_scrollServiceTargetControl
The control the bar sizes and docks itself against – the backing field of
ScrollServiceTargetControl.
_shouldAutoScrolingActionEnd
Set to end the auto-repeat loop that runs while an arrow or the track is held down; the bar sets it when the left button comes up.
_usingSibling
Not used by the library. Kept because it is part of the protected surface.