BeepScrollBar
Modern, customizable scrollbar control with horizontal and vertical orientations, smooth dragging, and comprehensive theming support
?? Table of Contents
Overview
BeepScrollBar provides a modern, fully customizable scrollbar control that can replace the standard Windows scrollbar with a more contemporary appearance. Supporting both horizontal and vertical orientations, it offers smooth dragging, hover effects, and comprehensive theming integration.
Built on the BeepControl foundation, BeepScrollBar features intelligent thumb sizing, proportional movement, keyboard navigation, mouse wheel support, and seamless integration with custom container controls. Perfect for modern interfaces requiring custom scrolling experiences.
Key Features
?? Dual Orientation
Supports both vertical and horizontal scrolling with automatic sizing
??? Smooth Interaction
Drag and drop thumb movement with immediate visual feedback
?? Keyboard Support
Arrow keys, Page Up/Down, and mouse wheel navigation
?? Customizable Colors
Track, thumb, hover, and active state color customization
?? Proportional Sizing
Intelligent thumb sizing based on content ratio and large change values
?? Theme Integration
Full theme support with specialized scrollbar color properties
Visual Preview
Vertical ScrollBar
Vertical BeepScrollBar with thumb positioned at 30% of range
Horizontal ScrollBar
Horizontal BeepScrollBar with proportional thumb sizing
Interactive States
Different scrollbar states: normal, hover, and active (dragging)
Basic Usage
Vertical ScrollBar
// Create a vertical scrollbar
var verticalScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Vertical,
Location = new Point(200, 50),
Size = new Size(15, 200),
Minimum = 0,
Maximum = 100,
Value = 0,
LargeChange = 10,
SmallChange = 1
};
// Handle value changes
verticalScrollBar.ValueChanged += (sender, e) =>
{
var scrollBar = sender as BeepScrollBar;
// Console.WriteLine($"ScrollBar value: {scrollBar.Value}");
// Update content position based on scrollbar value
UpdateContentPosition(scrollBar.Value);
};
// Handle scroll events (fired on any scroll action)
verticalScrollBar.Scroll += (sender, e) =>
{
var scrollBar = sender as BeepScrollBar;
// Perform smooth scrolling or animation
SmoothScrollToPosition(scrollBar.Value);
};
this.Controls.Add(verticalScrollBar);
Horizontal ScrollBar
// Create a horizontal scrollbar
var horizontalScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Horizontal,
Location = new Point(50, 300),
Size = new Size(200, 15),
Minimum = 0,
Maximum = 500,
Value = 0,
LargeChange = 50,
SmallChange = 5
};
// Handle scrolling for horizontal content
horizontalScrollBar.ValueChanged += (sender, e) =>
{
var scrollBar = sender as BeepScrollBar;
// Update horizontal scroll position
contentPanel.AutoScrollPosition = new Point(scrollBar.Value, 0);
};
this.Controls.Add(horizontalScrollBar);
Custom Appearance
// Create scrollbar with custom colors
var customScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Vertical,
Location = new Point(250, 50),
Size = new Size(12, 200),
// Custom colors
TrackColor = Color.FromArgb(240, 240, 240),
ThumbColor = Color.FromArgb(100, 100, 100),
ThumbColorHover = Color.FromArgb(80, 80, 80),
ThumbColorActive = Color.FromArgb(60, 60, 60),
// Range settings
Minimum = 0,
Maximum = 1000,
LargeChange = 100,
SmallChange = 10
};
// Apply theme colors
customScrollBar.ApplyTheme();
this.Controls.Add(customScrollBar);
Properties
Behavior Properties
| Property | Type | Default | Description |
|---|---|---|---|
ScrollOrientation |
Orientation | Vertical | Orientation of the scrollbar (Vertical or Horizontal) |
Value |
int | 0 | Current scroll position value |
Minimum |
int | 0 | Minimum scroll value |
Maximum |
int | 100 | Maximum scroll value |
LargeChange |
int | 10 | Value change for page up/down and track clicks |
SmallChange |
int | 1 | Value change for arrow keys and mouse wheel |
Appearance Properties
| Property | Type | Default | Description |
|---|---|---|---|
TrackColor |
Color | ControlDark | Color of the scrollbar track (background) |
ThumbColor |
Color | ControlDarkDark | Color of the scrollbar thumb (normal state) |
ThumbColorHover |
Color | ControlDark | Color of the scrollbar thumb when hovering |
ThumbColorActive |
Color | ControlDarkDark | Color of the scrollbar thumb when dragging |
Size Guidelines
| Orientation | Recommended Width | Recommended Height | Minimum Length |
|---|---|---|---|
| Vertical | 10-20 pixels | 100+ pixels | 50 pixels |
| Horizontal | 100+ pixels | 10-20 pixels | 50 pixels |
Events
| Event | Event Args | Description |
|---|---|---|
ValueChanged |
EventHandler | Fired when the Value property changes |
Scroll |
EventHandler | Fired on any scroll action (drag, click, keyboard) |
Event Handling
var scrollBar = new BeepScrollBar();
// Handle value changes for precise positioning
scrollBar.ValueChanged += (sender, e) =>
{
var sb = sender as BeepScrollBar;
// Calculate percentage
double percentage = (double)(sb.Value - sb.Minimum) / (sb.Maximum - sb.Minimum);
// Update content position
UpdateContentPosition(percentage);
// Update status
statusLabel.Text = $"Position: {sb.Value}/{sb.Maximum} ({percentage:P0})";
};
// Handle scroll events for animation or feedback
scrollBar.Scroll += (sender, e) =>
{
var sb = sender as BeepScrollBar;
// Trigger scroll animation
if (enableSmoothScrolling)
{
AnimateToPosition(sb.Value);
}
// Update scroll indicators
UpdateScrollIndicators(sb.Value, sb.Maximum);
// Log scroll activity
LogScrollActivity(sb.Value);
};
Examples
Custom Scrollable Panel
public class CustomScrollablePanel : Panel
{
private BeepScrollBar verticalScrollBar;
private BeepScrollBar horizontalScrollBar;
private Panel contentPanel;
private Size contentSize;
public CustomScrollablePanel()
{
SetupScrollablePanelContent();
SetupScrollBars();
UpdateScrollBars();
}
private void SetupScrollablePanelContent()
{
// Content panel that can be larger than visible area
contentPanel = new Panel
{
Location = new Point(0, 0),
BackColor = Color.White,
BorderStyle = BorderStyle.None
};
// Set initial content size
contentSize = new Size(800, 600);
contentPanel.Size = contentSize;
this.Controls.Add(contentPanel);
}
private void SetupScrollBars()
{
// Vertical scrollbar
verticalScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Vertical,
Dock = DockStyle.Right,
Width = 16,
Visible = false
};
verticalScrollBar.ValueChanged += OnVerticalScroll;
// Horizontal scrollbar
horizontalScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Horizontal,
Dock = DockStyle.Bottom,
Height = 16,
Visible = false
};
horizontalScrollBar.ValueChanged += OnHorizontalScroll;
this.Controls.AddRange(new Control[] { verticalScrollBar, horizontalScrollBar });
}
private void OnVerticalScroll(object sender, EventArgs e)
{
var scrollBar = sender as BeepScrollBar;
// Update content panel position
int newY = -scrollBar.Value;
contentPanel.Location = new Point(contentPanel.Location.X, newY);
}
private void OnHorizontalScroll(object sender, EventArgs e)
{
var scrollBar = sender as BeepScrollBar;
// Update content panel position
int newX = -scrollBar.Value;
contentPanel.Location = new Point(newX, contentPanel.Location.Y);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
UpdateScrollBars();
}
private void UpdateScrollBars()
{
if (contentPanel == null) return;
// Calculate available area (excluding scrollbar space)
int availableWidth = this.Width - (verticalScrollBar.Visible ? verticalScrollBar.Width : 0);
int availableHeight = this.Height - (horizontalScrollBar.Visible ? horizontalScrollBar.Height : 0);
// Determine if scrollbars are needed
bool needVertical = contentSize.Height > availableHeight;
bool needHorizontal = contentSize.Width > availableWidth;
// Adjust available area if scrollbars are needed
if (needVertical) availableWidth -= verticalScrollBar.Width;
if (needHorizontal) availableHeight -= horizontalScrollBar.Height;
// Re-check in case adding one scrollbar affects the other
needVertical = contentSize.Height > availableHeight;
needHorizontal = contentSize.Width > availableWidth;
// Configure vertical scrollbar
verticalScrollBar.Visible = needVertical;
if (needVertical)
{
verticalScrollBar.Minimum = 0;
verticalScrollBar.Maximum = contentSize.Height - availableHeight;
verticalScrollBar.LargeChange = Math.Max(1, availableHeight / 10);
verticalScrollBar.SmallChange = 20;
}
// Configure horizontal scrollbar
horizontalScrollBar.Visible = needHorizontal;
if (needHorizontal)
{
horizontalScrollBar.Minimum = 0;
horizontalScrollBar.Maximum = contentSize.Width - availableWidth;
horizontalScrollBar.LargeChange = Math.Max(1, availableWidth / 10);
horizontalScrollBar.SmallChange = 20;
}
}
public void SetContentSize(Size newSize)
{
contentSize = newSize;
contentPanel.Size = contentSize;
UpdateScrollBars();
}
public void ScrollToPosition(Point position)
{
if (verticalScrollBar.Visible)
{
verticalScrollBar.Value = Math.Max(verticalScrollBar.Minimum,
Math.Min(position.Y, verticalScrollBar.Maximum));
}
if (horizontalScrollBar.Visible)
{
horizontalScrollBar.Value = Math.Max(horizontalScrollBar.Minimum,
Math.Min(position.X, horizontalScrollBar.Maximum));
}
}
public void ScrollToTop()
{
if (verticalScrollBar.Visible)
verticalScrollBar.Value = verticalScrollBar.Minimum;
}
public void ScrollToBottom()
{
if (verticalScrollBar.Visible)
verticalScrollBar.Value = verticalScrollBar.Maximum;
}
}
Image Viewer with Custom Scrollbars
public class ImageViewerControl : UserControl
{
private BeepScrollBar vScrollBar;
private BeepScrollBar hScrollBar;
private PictureBox pictureBox;
private Image currentImage;
private float zoomFactor = 1.0f;
public ImageViewerControl()
{
SetupImageViewer();
}
private void SetupImageViewer()
{
this.BackColor = Color.Gray;
// Picture box for image display
pictureBox = new PictureBox
{
SizeMode = PictureBoxSizeMode.Normal,
Location = new Point(0, 0),
BackColor = Color.Transparent
};
// Vertical scrollbar
vScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Vertical,
Dock = DockStyle.Right,
Width = 18,
Visible = false
};
vScrollBar.ValueChanged += OnVerticalScroll;
// Horizontal scrollbar
hScrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Horizontal,
Dock = DockStyle.Bottom,
Height = 18,
Visible = false
};
hScrollBar.ValueChanged += OnHorizontalScroll;
this.Controls.AddRange(new Control[] { pictureBox, vScrollBar, hScrollBar });
// Handle mouse wheel for zooming
this.MouseWheel += OnMouseWheel;
}
public void LoadImage(Image image)
{
currentImage = image;
UpdateImageDisplay();
}
private void UpdateImageDisplay()
{
if (currentImage == null) return;
// Calculate scaled image size
int scaledWidth = (int)(currentImage.Width * zoomFactor);
int scaledHeight = (int)(currentImage.Height * zoomFactor);
pictureBox.Size = new Size(scaledWidth, scaledHeight);
pictureBox.Image = currentImage;
UpdateScrollBars();
}
private void UpdateScrollBars()
{
if (currentImage == null) return;
// Calculate available viewing area
int viewWidth = this.Width - (vScrollBar.Visible ? vScrollBar.Width : 0);
int viewHeight = this.Height - (hScrollBar.Visible ? hScrollBar.Height : 0);
// Check if scrollbars are needed
bool needVScroll = pictureBox.Height > viewHeight;
bool needHScroll = pictureBox.Width > viewWidth;
// Update available area if scrollbars will be shown
if (needVScroll) viewWidth -= vScrollBar.Width;
if (needHScroll) viewHeight -= hScrollBar.Height;
// Re-check after accounting for scrollbar space
needVScroll = pictureBox.Height > viewHeight;
needHScroll = pictureBox.Width > viewWidth;
// Configure vertical scrollbar
vScrollBar.Visible = needVScroll;
if (needVScroll)
{
vScrollBar.Minimum = 0;
vScrollBar.Maximum = pictureBox.Height - viewHeight;
vScrollBar.LargeChange = Math.Max(1, viewHeight);
vScrollBar.SmallChange = 20;
}
// Configure horizontal scrollbar
hScrollBar.Visible = needHScroll;
if (needHScroll)
{
hScrollBar.Minimum = 0;
hScrollBar.Maximum = pictureBox.Width - viewWidth;
hScrollBar.LargeChange = Math.Max(1, viewWidth);
hScrollBar.SmallChange = 20;
}
// Center image if smaller than view area
if (!needVScroll && !needHScroll)
{
pictureBox.Location = new Point(
(viewWidth - pictureBox.Width) / 2,
(viewHeight - pictureBox.Height) / 2
);
}
}
private void OnVerticalScroll(object sender, EventArgs e)
{
var scrollBar = sender as BeepScrollBar;
pictureBox.Location = new Point(pictureBox.Location.X, -scrollBar.Value);
}
private void OnHorizontalScroll(object sender, EventArgs e)
{
var scrollBar = sender as BeepScrollBar;
pictureBox.Location = new Point(-scrollBar.Value, pictureBox.Location.Y);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
UpdateScrollBars();
}
private void OnMouseWheel(object sender, MouseEventArgs e)
{
// Zoom in/out with mouse wheel
float zoomDelta = e.Delta > 0 ? 1.1f : 0.9f;
SetZoom(zoomFactor * zoomDelta);
}
public void SetZoom(float newZoom)
{
zoomFactor = Math.Max(0.1f, Math.Min(newZoom, 10.0f));
UpdateImageDisplay();
}
public void ZoomToFit()
{
if (currentImage == null) return;
float scaleX = (float)this.Width / currentImage.Width;
float scaleY = (float)this.Height / currentImage.Height;
SetZoom(Math.Min(scaleX, scaleY));
}
public void ZoomActualSize()
{
SetZoom(1.0f);
}
}
Theming
BeepScrollBar provides specialized theming with dedicated scrollbar color properties:
Theme Application
var scrollBar = new BeepScrollBar
{
ScrollOrientation = Orientation.Vertical,
Size = new Size(15, 200)
};
// Apply theme - automatically sets scrollbar-specific colors
scrollBar.Theme = "DarkTheme";
scrollBar.ApplyTheme();
// Theme sets these properties automatically:
// - BackColor: ScrollBarBackColor
// - TrackColor: ScrollBarTrackColor
// - ThumbColor: ScrollBarThumbColor
// - ThumbColorHover: ScrollBarHoverThumbColor
// - ThumbColorActive: ScrollBarActiveThumbColor
ScrollBar Theme Properties
- ScrollBarBackColor - Overall scrollbar background
- ScrollBarTrackColor - Track (groove) background color
- ScrollBarThumbColor - Thumb (slider) normal color
- ScrollBarHoverThumbColor - Thumb color when hovering
- ScrollBarActiveThumbColor - Thumb color when dragging
Custom ScrollBar Styling
// Create custom theme for scrollbars
var customTheme = new BeepTheme
{
ScrollBarBackColor = Color.FromArgb(248, 250, 252),
ScrollBarTrackColor = Color.FromArgb(226, 232, 240),
ScrollBarThumbColor = Color.FromArgb(148, 163, 184),
ScrollBarHoverThumbColor = Color.FromArgb(100, 116, 139),
ScrollBarActiveThumbColor = Color.FromArgb(71, 85, 105)
};
// Apply to scrollbar
BeepThemesManager.AddTheme("CustomScrollBar", customTheme);
scrollBar.Theme = "CustomScrollBar";
scrollBar.ApplyTheme();
// Or set colors directly
scrollBar.TrackColor = Color.LightGray;
scrollBar.ThumbColor = Color.DarkGray;
scrollBar.ThumbColorHover = Color.Gray;
scrollBar.ThumbColorActive = Color.Black;
Best Practices
?? Sizing Guidelines
- Width/Height: Use 12-20 pixels for scrollbar thickness
- Minimum length: Ensure at least 50 pixels of length for usability
- Proportional thumbs: Set LargeChange to match visible content ratio
- Auto-sizing: Update scrollbar ranges when content changes
?? User Experience
- Visual feedback: Use distinct hover and active states
- Smooth movement: Ensure responsive thumb dragging
- Keyboard support: Test arrow key and page up/down navigation
- Mouse wheel: Implement mouse wheel scrolling for convenience
?? Implementation
- Range validation: Ensure Maximum > Minimum + LargeChange
- Change values: Set appropriate SmallChange and LargeChange values
- Event handling: Use ValueChanged for position updates, Scroll for animations
- Performance: Minimize redraws during continuous scrolling
?? Visual Design
- Color contrast: Ensure sufficient contrast between track and thumb
- State indication: Make hover and active states clearly visible
- Theme consistency: Use theme colors for brand consistency
- Modern appearance: Consider rounded corners and subtle shadows
For large content, use virtual scrolling techniques and update only visible portions during scroll events to maintain smooth performance.
Set LargeChange to approximately the size of the visible content area for intuitive page-up/page-down behavior.
Ensure Maximum is always greater than Minimum + LargeChange, or the scrollbar may not function correctly.