Slider & ProgressBar
Range slider and determinate/indeterminate progress indicators
Namespace: Beep.Skia.Controls — Inherits: Slider → MaterialControl → SkiaComponent • ProgressBar → MaterialControl → SkiaComponent
Table of Contents
Overview
The Slider and ProgressBar controls provide Material Design 3.0 range input and progress feedback, rendered entirely with SkiaSharp. Slider lets users select a value from a range by dragging a thumb along a track, with optional tick marks and a value label. ProgressBar displays a determinate fill percentage or an indeterminate animated stripe to indicate ongoing activity.
Both controls use the active Material theme for track, thumb, and fill colors. The slider thumb scales up on press (with a ripple effect) and the progress bar supports a smooth fill animation when the value changes programmatically.
Snap to Steps
Slider supports an optional Step increment for discrete value snapping with visual tick marks.
Range Mode
Slider can render a two-thumb range selector for choosing a min/max interval.
Indeterminate Animation
ProgressBar's indeterminate mode draws a continuously animating stripe that loops horizontally.
Orientation
Both controls support horizontal and vertical orientations.
Slider Properties
| Property | Type | Description |
|---|---|---|
Min |
float |
Minimum value of the slider range. Default is 0. |
Max |
float |
Maximum value of the slider range. Default is 100. |
Value |
float |
Current value. Clamped to [Min, Max]. Setting this programmatically moves the thumb and updates the track fill proportionally. |
Step |
float |
Snap increment. When > 0, the value snaps to the nearest multiple of Step. Tick marks are rendered at each step interval. Default is 0 (continuous). |
Orientation |
SKOrientation |
Horizontal (default) or Vertical. Determines the track axis and thumb movement direction. Vertical sliders have their track drawn top-to-bottom. |
ThumbSize |
float |
Diameter of the circular thumb. Default is 20f. The thumb scales to 24f on press/hover with an animated transition. |
TrackThickness |
float |
Thickness of the track line. Default is 4f for the inactive portion and 6f for the active (filled) portion. |
ShowValueLabel |
bool |
When true, a floating label showing the current value appears above the thumb while dragging. Default is true. |
ValueFormat |
string |
Format string applied to the value label. Default is "0" (integer). Use "0.0" for one decimal, "0%" for percentage. |
IsRange |
bool |
When true, the slider renders two thumbs for selecting a min/max range. Default is false. |
RangeStart |
float |
Second thumb value for range mode. Used when IsRange is true. |
ShowTickMarks |
bool |
When true and Step > 0, small tick marks are rendered along the track at each step position. Default is true. |
IsHovered |
bool |
Read-only. Whether the mouse is over the slider's touch target area. |
IsDragging |
bool |
Read-only. Whether the thumb is currently being dragged via pointer. |
ProgressBar Properties
| Property | Type | Description |
|---|---|---|
Value |
float |
Current progress value. Clamped to [0, Max]. The filled portion of the track is Value / Max * Width. Ignored when IsIndeterminate is true. |
Max |
float |
Maximum value. Default is 100. Use 1.0 for 0–1 normalized progress. |
IsIndeterminate |
bool |
When true, the progress bar displays a continuously animating stripe instead of a determinate fill. The stripe moves horizontally on a loop. |
Style |
ProgressBarStyle |
Enum: Linear (default, horizontal bar) or Circular (a circular arc indicator). Circular style renders as an SVG-like arc. |
TrackThickness |
float |
Thickness of the progress bar track. Default is 4f for linear, 4f (stroke width) for circular. |
CornerRadius |
float |
Rounding of the linear track ends. Default is 2f (half of track thickness for fully rounded caps). |
FillColor |
SKColor |
Override color for the filled portion. When not set, uses Primary from the active theme. |
TrackColor |
SKColor |
Override color for the unfilled track. When not set, uses SurfaceVariant from the active theme. |
AnimationDuration |
float |
Duration in milliseconds for the smooth fill animation when Value changes. Default is 300. Set to 0 for instant updates. |
Circular ProgressBar
When Style = ProgressBarStyle.Circular, the control renders as a circular arc. Additional properties apply:
| Property | Type | Description |
|---|---|---|
ArcStartAngle | float | Starting angle in degrees for the arc. Default is -90 (top). |
ArcSweepAngle | float | The total sweep of the full arc in degrees. Default is 360. |
Events
| Event | Owner | Signature | Description |
|---|---|---|---|
ValueChanged |
Slider |
EventHandler<float> |
Raised as the slider value changes during drag or programmatic assignment. Fires continuously during dragging for live feedback. |
DragStarted |
Slider |
EventHandler |
Raised when the user begins dragging the thumb (pointer down on thumb). |
DragEnded |
Slider |
EventHandler |
Raised when the user releases the thumb (pointer up). The value is finalized. |
ValueChanged |
ProgressBar |
EventHandler<float> |
Raised when the animated value reaches its target. Not raised continuously; only at completion of the animation. |
Code Example
Continuous Slider with Value Label
var opacitySlider = new Slider
{
Min = 0,
Max = 100,
Value = 75,
ShowValueLabel = true,
ValueFormat = "0%",
X = 40, Y = 40,
Width = 300, Height = 56
};
opacitySlider.Initialize();
opacitySlider.ValueChanged += (s, val) =>
Console.WriteLine($"Opacity: {val}%");
drawingManager.AddComponent(opacitySlider);
drawingManager.RequestRedraw();
Stepped Slider with Tick Marks
var fontSizeSlider = new Slider
{
Min = 8,
Max = 48,
Value = 16,
Step = 4,
ShowTickMarks = true,
ShowValueLabel = true,
ValueFormat = "0px",
X = 40, Y = 120,
Width = 300, Height = 56
};
fontSizeSlider.Initialize();
fontSizeSlider.ValueChanged += (s, val) =>
{
int fontSize = (int)val;
textLabel.FontSize = fontSize;
textLabel.Invalidate();
};
drawingManager.AddComponent(fontSizeSlider);
Vertical Slider
var volumeSlider = new Slider
{
Min = 0,
Max = 100,
Value = 65,
Orientation = SKOrientation.Vertical,
ShowValueLabel = true,
X = 380, Y = 40,
Width = 56, Height = 200
};
volumeSlider.Initialize();
volumeSlider.ValueChanged += (s, val) =>
Console.WriteLine($"Volume: {val}");
drawingManager.AddComponent(volumeSlider);
Determinate and Indeterminate ProgressBars
var determinateBar = new ProgressBar
{
Value = 65,
Max = 100,
Style = ProgressBarStyle.Linear,
AnimationDuration = 500,
X = 40, Y = 260,
Width = 350, Height = 8
};
determinateBar.Initialize();
var indeterminateBar = new ProgressBar
{
IsIndeterminate = true,
Style = ProgressBarStyle.Linear,
X = 40, Y = 290,
Width = 350, Height = 8
};
indeterminateBar.Initialize();
drawingManager.AddComponent(determinateBar);
drawingManager.AddComponent(indeterminateBar);
Circular ProgressBar
var circularProgress = new ProgressBar
{
Value = 72,
Max = 100,
Style = ProgressBarStyle.Circular,
TrackThickness = 6,
X = 460, Y = 40,
Width = 80, Height = 80
};
circularProgress.Initialize();
var circularIndeterminate = new ProgressBar
{
IsIndeterminate = true,
Style = ProgressBarStyle.Circular,
TrackThickness = 6,
X = 460, Y = 140,
Width = 80, Height = 80
};
circularIndeterminate.Initialize();
drawingManager.AddComponent(circularProgress);
drawingManager.AddComponent(circularIndeterminate);
Range Slider (Two Thumbs)
var priceRange = new Slider
{
Min = 0,
Max = 1000,
Value = 200,
IsRange = true,
RangeStart = 800,
ValueFormat = "$0",
ShowTickMarks = true,
Step = 50,
X = 40, Y = 340,
Width = 380, Height = 56
};
priceRange.Initialize();
priceRange.ValueChanged += (s, val) =>
Console.WriteLine($"Range: ${priceRange.RangeStart} - ${val}");
drawingManager.AddComponent(priceRange);
drawingManager.RequestRedraw();
Tip
For real-time feedback during slider drag, subscribe to ValueChanged and update dependent components immediately. The slider's IsDragging property can be checked to distinguish programmatic changes from user interaction. Use DragEnded for expensive operations that should only fire once when the user finishes adjusting.