Beep Widget System
Self-contained, fully themed display/input widgets built on BaseControl. Drop any widget on a form, set a style, and it paints itself.
Stable
v1.0.164
TheTechIdea.Beep.Winform.Controls.Widgets
What are Beep Widgets?
Beep Widgets are self-contained, paint-based WinForms controls that deliver rich visual output without child controls. Each widget:
- Inherits from BaseControl — full theme support, Border, Padding, and Hover states come for free.
- Has a Style enum property that switches the entire visual rendering mode (e.g.
MetricWidgetStyle.GaugeMetric). - Uses an IWidgetPainter / WidgetContext pipeline — background, content, and foreground accents are drawn in three separate passes.
- Fires strongly-typed BeepEventDataArgs events for every meaningful user interaction.
- Re-applies the currently active BeepTheme automatically when the application theme changes.
Namespace:
Base class:
Toolbox category: Beep Widgets
TheTechIdea.Beep.Winform.Controls.WidgetsBase class:
BaseControl (→ Control)Toolbox category: Beep Widgets
Architecture
The widget rendering pipeline consists of three layers:
// IWidgetPainter interface
void Initialize(BaseControl owner, IBeepTheme theme);
WidgetContext AdjustLayout(Rectangle drawingRect, WidgetContext ctx);
void DrawBackground(Graphics g, WidgetContext ctx);
void DrawContent(Graphics g, WidgetContext ctx);
void DrawForegroundAccents(Graphics g, WidgetContext ctx);
void UpdateHitAreas(BaseControl owner, WidgetContext ctx, Action<string, Rectangle> notifyAreaHit);
The WidgetContext object carries all layout rectangles, colours, and data needed for a single paint pass. The widget control populates the context from its properties; the current painter reads it.
Painter Selection
When the Style property changes, the widget calls InitializePainter() which instantiates the matching concrete painter class and calls Initialize() followed by Invalidate().
// Example: changing a metric widget style at runtime
metricWidget.Style = MetricWidgetStyle.GaugeMetric;
// The widget automatically swaps in GaugeMetricPainter and repaints.
Quick Start
// 1. Drop any widget on a form, or create programmatically:
var metric = new BeepMetricWidget
{
Style = MetricWidgetStyle.ValueWithTrend,
Title = "Monthly Revenue",
Value = "$127,450",
TrendValue = "+8.3%",
ShowTrend = true,
Size = new Size(220, 120)
};
panel.Controls.Add(metric);
// 2. Handle events:
metric.ValueClicked += (s, e) => ShowRevenueDetail();
// 3. Theme changes are picked up automatically via ApplyTheme().
Using a Chart Widget
var chart = new BeepChartWidget
{
Style = ChartWidgetStyle.LineChart,
Title = "Sales Trend",
Values = new List<double> { 120, 135, 98, 160, 175, 210 },
Labels = new List<string> { "Jan","Feb","Mar","Apr","May","Jun" },
ShowLegend = true
};
chart.DataPointClicked += (s, e) => Console.WriteLine(e.Data);
Available Widgets (13)
Best Practices
- Set Size before adding to a container — each widget has a sensible default size but you should adjust it to fit your layout.
- Use Style enums, not magic numbers — always assign the strongly-typed enum value.
- Avoid overlapping widgets — widgets are GDI+ paint-based and do not clip to parent containers automatically.
- Let the theme engine drive colours — avoid hard-coding color properties; most colour properties default to the current theme values.
- Reuse widget instances — updating data properties and calling
Invalidate()is cheaper than creating a new widget. - Handle BeepEventDataArgs.Data — the
Dataproperty contains context-specific clicked-item data (index, value, label, etc.).