Advanced Examples
Advanced usage patterns for Beep Controls
Dynamic Theme & FormStyle Switching
Build a runtime theme switcher using BeepThemesManager and BeepiFormPro.FormStyle:
Runtime theme and FormStyle switcher
using TheTechIdea.Beep.Winform.Controls;
using TheTechIdea.Beep.Winform.Controls.Forms.ModernForm;
using TheTechIdea.Beep.Winform.Controls.ThemeManagement;
public class SettingsForm : BeepiFormPro
{
public SettingsForm()
{
Text = "Settings";
Size = new Size(500, 400);
FormStyle = FormStyle.Fluent;
// Theme selector
var themeCombo = new BeepComboBox();
themeCombo.Size = new Size(220, 35);
themeCombo.Location = new Point(20, 70);
// Populated from auto-discovered themes
foreach (var theme in BeepThemesManager.Themes)
themeCombo.Items.Add(theme.ThemeName);
themeCombo.SelectedIndexChanged += (s, e) =>
{
var name = themeCombo.SelectedItem?.ToString();
if (!string.IsNullOrEmpty(name))
BeepThemesManager.ApplyTheme(name);
};
// FormStyle selector
var styleCombo = new BeepComboBox();
styleCombo.Size = new Size(220, 35);
styleCombo.Location = new Point(20, 120);
foreach (FormStyle style in Enum.GetValues(typeof(FormStyle)))
styleCombo.Items.Add(style.ToString());
styleCombo.SelectedIndexChanged += (s, e) =>
{
if (Enum.TryParse<FormStyle>(
styleCombo.SelectedItem?.ToString(), out var fs))
{
FormStyle = fs; // BeepiFormPro switches painter instantly
}
};
Controls.Add(themeCombo);
Controls.Add(styleCombo);
}
}
Working with BaseControl Painters
The PainterKind property switches the entire rendering strategy at runtime.
Under the hood, BaseControl calls EnsurePainter() which creates the appropriate painter
from the PaintersFactory:
Switching PainterKind at runtime
// Render pipeline: OnPaint → EnsurePainter → _painter.Paint → DrawingRect
// Derived controls paint their content into DrawingRect only
// Switch painter at runtime
myPanel.PainterKind = BaseControlPainterKind.Auto; // Follow global style
myPanel.PainterKind = BaseControlPainterKind.Glassmorphism; // Frosted glass
myPanel.PainterKind = BaseControlPainterKind.Neumorphism; // Soft 3D
myPanel.PainterKind = BaseControlPainterKind.Card; // Card with shadow
myPanel.PainterKind = BaseControlPainterKind.NeoBrutalist; // Bold outlines
// Change the border/background style via BeepControlStyle (mapped from BeepStyling)
myButton.BorderPainter = BeepControlStyle.Material3;
myButton.BorderPainter = BeepControlStyle.FluentDesign;
Using BeepStyling Design Systems
BeepStyling manages 27 design systems. Setting CurrentControlStyle globally
changes which background, border, shadow, and text painters are used:
Global design system switching
using TheTechIdea.Beep.Winform.Controls.Styling;
// Switch the entire app to a different design system
BeepStyling.SetControlStyle(BeepControlStyle.Material3);
// or BeepControlStyle.FluentDesign, iOS15, AntDesign, ChakraUI,
// TailwindCSS, Bootstrap5, Carbon, Atlassian, Lightning, etc.
// Each design system has its own painters in these folders:
// BackgroundPainters/ (36) — e.g., Material3BackgroundPainter
// BorderPainters/ (27) — e.g., FluentDesignBorderPainter
// ShadowPainters/ (27) — e.g., iOS15ShadowPainter
// TextPainters/ (5) — e.g., MaterialTextPainter
// PathPainters/ (23) — shape/path rendering
// Query colors from the active style
Color primary = BeepStyling.GetColor("Primary");
Color bg = BeepStyling.GetColor("Background");
BeepiFormPro Form Painter Architecture
Each FormStyle maps to a dedicated IFormPainter class in the Painters/ subfolder.
Key classes involved:
FormPainterMetrics— Calculates caption bar height, button sizes, padding, border widthsBeepiFormProHitAreaManager— Manages close/min/max button hit areas, title bar drag regionBeepiFormProInteractionManager— Handles hover, press, and release states for caption buttonsActivePainter— The currentIFormPainterinstance (e.g.,MaterialFormPainter,CyberpunkFormPainter)
FormStyle to painter mapping
// BeepiFormPro automatically selects the right painter:
// FormStyle.Material → MaterialFormPainter
// FormStyle.MacOS → MacOSFormPainter
// FormStyle.Fluent → FluentFormPainter
// FormStyle.Cyberpunk → CyberpunkFormPainter
// FormStyle.Terminal → TerminalFormPainter
// ... and 30+ more
// When you change FormStyle, the form:
// 1. Creates/caches the new painter via EnsureLayoutCalculated()
// 2. Recalculates FormPainterMetrics
// 3. Updates HitAreaManager regions
// 4. Invalidates — triggers full repaint with new painter
Creating a Custom Control
To create your own control, inherit from BaseControl and override the paint method.
The painter handles borders, backgrounds, and shadows — you only render your content into DrawingRect:
Custom control inheriting BaseControl
using TheTechIdea.Beep.Winform.Controls.Base;
public class MyCustomControl : BaseControl
{
public string CustomText { get; set; } = "Hello";
protected override void DrawContent(Graphics g, Rectangle drawRect)
{
// drawRect is already inset by the painter's borders/padding
using var brush = new SolidBrush(CurrentTheme?.TextColor ?? Color.Black);
using var font = new Font("Segoe UI", 12f);
g.DrawString(CustomText, font, brush, drawRect.Location);
}
}
// Usage
var custom = new MyCustomControl();
custom.PainterKind = BaseControlPainterKind.Card;
custom.CustomText = "My Content";
custom.Size = new Size(200, 100);
Theme Propagation in BeepiFormPro
BeepiFormPro.ApplyTheme() walks all child controls and applies the theme to any IBeepUIComponent:
Theme propagation in BeepiFormPro
// This happens automatically when BeepThemesManager fires ThemeChanged.
// You can also trigger it manually:
myForm.ApplyTheme(BeepThemesManager.GetTheme("Dracula"));
// Under the hood:
// 1. Sets CurrentTheme on the form
// 2. Iterates all Controls recursively
// 3. For each IBeepUIComponent child, calls child.ApplyTheme(theme)
// 4. Each child re-reads colors/fonts from the theme and invalidates