BeepProgressBar
Modern progress indicator with animations, text display, and theming support
📑 Table of Contents
Overview
BeepProgressBar is an enhanced progress indicator control that extends the standard Windows Forms ProgressBar with modern styling, smooth animations, text overlays, and comprehensive theming support for displaying operation progress to users.
Built on the BeepControl foundation, BeepProgressBar provides multiple visual styles,
percentage text display, color gradients, indeterminate progress modes, and seamless integration
with async operations for better user experience.
Key Features
📊 Multiple Styles
Standard, gradient, segmented, and indeterminate progress styles
📝 Text Display
Customizable text overlay showing percentage, status, or custom messages
🎬 Smooth Animations
Smooth progress transitions and animated indeterminate mode
🌈 Color Gradients
Support for gradient fills with customizable color schemes
🔄 Async Integration
Built-in support for async operations with progress reporting
🎨 Theme Support
Full integration with Beep theming system for consistent styling
Basic Usage
Simple Progress Bar
// Create a basic progress bar
var progressBar = new BeepProgressBar
{
Minimum = 0,
Maximum = 100,
Value = 0,
Size = new Size(300, 25),
Location = new Point(10, 10),
ShowText = true
};
// Add to form
this.Controls.Add(progressBar);
// Update progress
progressBar.Value = 50; // 50% complete
Progress with Custom Text
// Create progress bar with custom text
var customProgressBar = new BeepProgressBar
{
Minimum = 0,
Maximum = 100,
Value = 0,
Size = new Size(400, 30),
Location = new Point(10, 50),
ShowText = true,
TextFormat = "Processing: {0}% ({1}/{2})",
ProgressBarStyle = ProgressBarStyle.Continuous
};
// Update with custom text
customProgressBar.SetProgress(25, "Loading files...");
customProgressBar.SetProgress(75, "Analyzing data...");
customProgressBar.SetProgress(100, "Complete!");
Indeterminate Progress
// Create indeterminate progress bar for unknown duration tasks
var indeterminateProgress = new BeepProgressBar
{
Style = ProgressBarStyle.Marquee,
MarqueeAnimationSpeed = 50,
Size = new Size(300, 25),
Location = new Point(10, 90),
ShowText = true,
Text = "Processing..."
};
// Start/stop indeterminate animation
indeterminateProgress.StartMarquee();
// ... perform work ...
indeterminateProgress.StopMarquee();
Use indeterminate progress bars for operations where you can't estimate completion time, and determinate progress bars when you can track actual progress.
Progress Styles
Available Styles
| Style | Description | Use Case |
|---|---|---|
Continuous |
Smooth filled bar with no segments | Standard progress indication |
Blocks |
Segmented blocks that fill individually | Step-by-step progress visualization |
Marquee |
Animated scrolling pattern | Indeterminate progress indication |
Gradient |
Smooth color gradient fill | Modern, visually appealing progress |
Style Configuration
// Continuous style (default)
var continuousProgress = new BeepProgressBar
{
ProgressBarStyle = ProgressBarStyle.Continuous,
ForeColor = Color.Green,
BackColor = Color.LightGray
};
// Blocks/segmented style
var blocksProgress = new BeepProgressBar
{
ProgressBarStyle = ProgressBarStyle.Blocks,
ForeColor = Color.Blue,
BlockSize = 8,
BlockSpacing = 2
};
// Gradient style
var gradientProgress = new BeepProgressBar
{
ProgressBarStyle = ProgressBarStyle.Gradient,
GradientStartColor = Color.LightBlue,
GradientEndColor = Color.DarkBlue,
ShowGradient = true
};
// Marquee style for indeterminate progress
var marqueeProgress = new BeepProgressBar
{
Style = ProgressBarStyle.Marquee,
MarqueeAnimationSpeed = 100, // Animation speed
ForeColor = Color.Orange
};
Properties
Core Properties
| Property | Type | Description |
|---|---|---|
Value |
int | Current progress value |
Minimum |
int | Minimum value (usually 0) |
Maximum |
int | Maximum value (usually 100) |
ProgressBarStyle |
ProgressBarStyle | Visual style of the progress bar |
MarqueeAnimationSpeed |
int | Animation speed for marquee style |
Text Display Properties
ShowText bool
Whether to display text overlay on progress bar
TextFormat string
Format string for percentage display
TextAlign ContentAlignment
Alignment of text within progress bar
TextColor Color
Color of overlay text
Appearance Properties
| Property | Type | Description |
|---|---|---|
ForeColor |
Color | Progress bar fill color |
BackColor |
Color | Background color of unfilled area |
BorderStyle |
BorderStyle | Border style around progress bar |
BorderRadius |
int | Corner radius for rounded appearance |
ShowGradient |
bool | Whether to use gradient fill |
GradientStartColor |
Color | Starting color for gradient |
GradientEndColor |
Color | Ending color for gradient |
Events
| Event | Description | When Triggered |
|---|---|---|
ValueChanged |
Progress value has changed | When Value property is modified |
ProgressCompleted |
Progress has reached maximum | When Value equals Maximum |
ProgressStarted |
Progress has started from minimum | When Value changes from Minimum |
Event Handling
var progressBar = new BeepProgressBar();
// Handle value changes
progressBar.ValueChanged += (sender, e) => {
var pb = sender as BeepProgressBar;
double percentage = (double)pb.Value / pb.Maximum * 100;
// Console.WriteLine($"Progress: {percentage:F1}%");
// Update UI based on progress
if (percentage >= 50)
{
pb.ForeColor = Color.Orange;
}
if (percentage >= 75)
{
pb.ForeColor = Color.Green;
}
};
// Handle completion
progressBar.ProgressCompleted += (sender, e) => {
MessageBox.Show("Operation completed successfully!");
// Reset or hide progress bar
progressBar.Visible = false;
// Enable UI elements
EnableControls();
};
// Handle start
progressBar.ProgressStarted += (sender, e) => {
// Console.WriteLine("Progress started");
// Disable UI elements during progress
DisableControls();
};
Examples
File Download Progress
public class FileDownloadForm : Form
{
private BeepProgressBar downloadProgress;
private BeepButton downloadButton;
private BeepLabel statusLabel;
public FileDownloadForm()
{
InitializeControls();
}
private void InitializeControls()
{
// Download progress bar
downloadProgress = new BeepProgressBar
{
Size = new Size(400, 30),
Location = new Point(20, 20),
ShowText = true,
TextFormat = "Downloading: {0}% ({1:F1} MB / {2:F1} MB)",
Visible = false,
ShowGradient = true,
GradientStartColor = Color.LightBlue,
GradientEndColor = Color.Blue
};
// Status label
statusLabel = new BeepLabel
{
Size = new Size(400, 20),
Location = new Point(20, 60),
Text = "Ready to download"
};
// Download button
downloadButton = new BeepButton
{
Text = "Start Download",
Size = new Size(120, 35),
Location = new Point(20, 90)
};
downloadButton.Click += DownloadButton_Click;
// Progress events
downloadProgress.ValueChanged += (s, e) => {
var percentage = (double)downloadProgress.Value / downloadProgress.Maximum * 100;
if (percentage < 50)
downloadProgress.ForeColor = Color.Red;
else if (percentage < 80)
downloadProgress.ForeColor = Color.Orange;
else
downloadProgress.ForeColor = Color.Green;
};
downloadProgress.ProgressCompleted += (s, e) => {
statusLabel.Text = "Download completed successfully!";
downloadButton.Text = "Download Again";
downloadButton.Enabled = true;
};
this.Controls.AddRange(new Control[]
{
downloadProgress, statusLabel, downloadButton
});
}
private async void DownloadButton_Click(object sender, EventArgs e)
{
downloadButton.Enabled = false;
downloadButton.Text = "Downloading...";
downloadProgress.Visible = true;
downloadProgress.Value = 0;
try
{
await SimulateDownload();
}
catch (Exception ex)
{
MessageBox.Show($"Download failed: {ex.Message}");
statusLabel.Text = "Download failed";
downloadButton.Enabled = true;
downloadButton.Text = "Retry Download";
}
}
private async Task SimulateDownload()
{
var totalSize = 50.5; // MB
var progress = new Progress(bytesReceived => {
var percentage = (bytesReceived / totalSize) * 100;
downloadProgress.Value = (int)percentage;
statusLabel.Text = $"Downloaded {bytesReceived:F1} MB of {totalSize:F1} MB";
});
// Simulate download progress
for (double i = 0; i <= totalSize; i += 0.5)
{
await Task.Delay(50); // Simulate network delay
((IProgress)progress).Report(i);
}
}
}
Multi-Step Process Progress
public class ProcessingForm : Form
{
private BeepProgressBar overallProgress;
private BeepProgressBar stepProgress;
private BeepLabel currentStepLabel;
private readonly string[] processSteps = {
"Initializing...",
"Loading data...",
"Processing records...",
"Generating report...",
"Saving results...",
"Cleaning up..."
};
public ProcessingForm()
{
InitializeControls();
}
private void InitializeControls()
{
// Overall progress
overallProgress = new BeepProgressBar
{
Size = new Size(500, 25),
Location = new Point(20, 20),
Maximum = processSteps.Length,
ShowText = true,
TextFormat = "Overall Progress: {0}%",
ShowGradient = true,
GradientStartColor = Color.LightGreen,
GradientEndColor = Color.DarkGreen
};
// Step progress
stepProgress = new BeepProgressBar
{
Size = new Size(500, 20),
Location = new Point(20, 60),
Maximum = 100,
ShowText = true,
TextFormat = "Current Step: {0}%",
ForeColor = Color.Blue
};
// Current step label
currentStepLabel = new BeepLabel
{
Size = new Size(500, 20),
Location = new Point(20, 90),
Text = "Ready to start processing"
};
this.Controls.AddRange(new Control[]
{
overallProgress, stepProgress, currentStepLabel
});
}
public async Task ProcessData()
{
overallProgress.Value = 0;
for (int step = 0; step < processSteps.Length; step++)
{
currentStepLabel.Text = processSteps[step];
stepProgress.Value = 0;
// Simulate step progress
for (int i = 0; i <= 100; i += 5)
{
stepProgress.Value = i;
await Task.Delay(50);
}
overallProgress.Value = step + 1;
await Task.Delay(100);
}
currentStepLabel.Text = "Processing completed!";
}
}
Async Operation with Progress Reporting
public class AsyncProgressExample : Form
{
private BeepProgressBar progressBar;
private BeepButton startButton;
private CancellationTokenSource cancellationTokenSource;
private async void StartButton_Click(object sender, EventArgs e)
{
startButton.Enabled = false;
cancellationTokenSource = new CancellationTokenSource();
progressBar.Value = 0;
progressBar.Visible = true;
var progress = new Progress(value => {
progressBar.Value = value;
progressBar.Text = $"Processing item {value} of {progressBar.Maximum}";
});
try
{
await ProcessItemsAsync(progress, cancellationTokenSource.Token);
MessageBox.Show("Processing completed!");
}
catch (OperationCanceledException)
{
MessageBox.Show("Processing was cancelled.");
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}");
}
finally
{
startButton.Enabled = true;
progressBar.Visible = false;
}
}
private async Task ProcessItemsAsync(IProgress progress, CancellationToken cancellationToken)
{
const int totalItems = 100;
progressBar.Maximum = totalItems;
for (int i = 1; i <= totalItems; i++)
{
cancellationToken.ThrowIfCancellationRequested();
// Simulate work
await Task.Delay(50, cancellationToken);
// Report progress
progress?.Report(i);
}
}
}
Theming
BeepProgressBar integrates seamlessly with the Beep theming system for consistent visual styling:
Theme Application
var progressBar = new BeepProgressBar
{
Theme = "DarkTheme"
};
// Theme automatically applies:
// - ProgressBarBackColor (background)
// - ProgressBarForeColor (fill color)
// - ProgressBarBorderColor (border)
// - ProgressBarTextColor (text overlay)
// Apply theme manually
progressBar.ApplyTheme();
// Override specific theme colors
progressBar.ForeColor = Color.LimeGreen;
progressBar.BackColor = Color.DarkGray;
progressBar.TextColor = Color.White;
Theme-Responsive Features
- Background Colors - Automatically use theme background colors
- Progress Colors - Adapt fill colors to theme accent colors
- Text Colors - Use theme text colors for overlay text
- Border Styles - Apply theme border colors and styles
- Gradient Colors - Theme-aware gradient color schemes
Use gradient colors that complement your theme's color palette for the most professional appearance.
2026 Painter API Update
The progress bar pipeline now supports typed painter context, capability metadata, and runtime style/color profiles for deterministic rendering across painter kinds.
Modern Runtime Configuration
var progress = new BeepProgressBar
{
PainterKind = ProgressPainterKind.StepperCircles,
UseThemeColors = false,
StyleProfile =
{
ControlStyle = BeepControlStyle.Material3,
BorderRadius = 8,
AnimateValueChanges = true
},
ColorProfile =
{
BackgroundColor = Color.FromArgb(245, 247, 250),
ProgressColor = Color.FromArgb(63, 81, 181),
TextColor = Color.White
}
};
progress.Parameters = new Dictionary<string, object>
{
["Steps"] = 5,
["Current"] = 2,
["Labels"] = new[] { "Draft", "Review", "QA", "UAT", "Done" }
};
- Typed state/context: Painters receive normalized progress state through the control pipeline.
- Capability metadata: Interactive painters advertise hit-area and keyboard behavior for consistent UX.
- DPI-first geometry: Core layout and step/chevron painters scale using shared helpers.
- Tokenized typography/icons: Font and icon helpers are used for consistent rendering.
- Accessibility semantics: Step-based and animated variants expose richer screen-reader summaries.
Best Practices
🎨 User Experience
- Show meaningful text: Display percentage, current operation, or time remaining
- Choose appropriate styles: Use continuous for smooth progress, blocks for steps
- Provide feedback: Update progress frequently enough to show activity
- Handle completion: Always provide clear indication when operations complete
- Use indeterminate wisely: Only for truly unknown duration operations
⚡ Performance
- Limit update frequency: Don't update progress more than 30-60 times per second
- Use async patterns: Always run long operations on background threads
- Batch progress updates: Group small increments to reduce UI updates
- Dispose properly: Clean up progress bars and cancel tokens when done
♿ Accessibility
- Provide text alternatives: Always show progress text for screen readers
- Use sufficient contrast: Ensure progress colors are visible to all users
- Keyboard support: Allow cancellation via keyboard shortcuts
- Status announcements: Announce major progress milestones
📊 Progress Reporting
- Accurate estimates: Only show determinate progress when you can estimate duration
- Meaningful increments: Update progress in logical steps, not arbitrary percentages
- Handle errors gracefully: Provide clear error messages and recovery options
- Allow cancellation: Provide cancel functionality for long-running operations
Always update progress bars from the UI thread. Use Control.Invoke() or Progress<T> when updating from background threads.
Use the Progress<T> class with async operations for thread-safe progress reporting that automatically marshals to the UI thread.