Lightweight dark mode and high-DPI theming for Windows Forms that augments the standard controls instead of replacing them.
Most WinForms theming libraries (Krypton, ReaLTaiizor, MaterialSkin, Guna) give you a whole new set of custom controls you must rebuild your UI around. WinControls takes the opposite approach: keep your existing standard controls, and recolor them in place. Drop it into an existing app and get a modern light/dark look with a couple of lines.
Targets .NET Framework 4.6.2 and .NET 8 (Windows) from a single package.
- Native dark title bar via the Desktop Window Manager (
DwmSetWindowAttribute), Windows 10 1809+ and Windows 11. A safe no-op on older systems. - Recursive control-tree recoloring for the standard controls: Form, Button, TextBox, ComboBox, ListBox, CheckBox, RadioButton, Label, LinkLabel, DataGridView, ListView, TreeView, and common containers.
- OS theme following: resolve
ThemeMode.Systemfrom the user's Windows app theme preference. - No custom control types: nothing to rebuild your forms around.
dotnet add package WinControls
Theme a form in its constructor:
using WinControls.Theming;
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
ThemeManager.Apply(this, ThemeMode.System); // dark title bar + recolor, follows OS
}
}That's it. ThemeManager.Apply:
- Resolves the palette (
Systemfollows the OS;Dark/Lightare explicit). - Sets the native title bar light/dark via DWM.
- Recolors the entire control tree.
private void btnDark_Click(object sender, EventArgs e)
=> ThemeManager.Apply(this, ThemeMode.Dark);Microsoft.Win32.SystemEvents.UserPreferenceChanged += (_, _) =>
ThemeManager.Refresh(this, ThemeMode.System);var brand = new ThemePalette(
isDark: true,
windowBackground: Color.FromArgb(18, 18, 24),
surface: Color.FromArgb(28, 28, 38),
foreground: Color.White,
mutedForeground: Color.Gray,
border: Color.FromArgb(50, 50, 64),
accent: Color.MediumPurple,
accentForeground: Color.White,
controlBackground:Color.FromArgb(34, 34, 46),
controlBorder: Color.FromArgb(70, 70, 90),
selectionBackground: Color.MediumPurple,
selectionForeground: Color.White);
ThemeManager.ApplyPalette(this, brand);| Type | Purpose |
|---|---|
ThemeManager |
Entry point: Apply(form, mode), ApplyPalette(form, palette), Refresh(...). |
ThemePalette |
Immutable color set; built-in Dark / Light. |
ThemeMode |
Light, Dark, or System. |
ThemeApplier |
Recolors a control tree in place (use directly to theme a sub-panel). |
SystemTheme |
Reads the OS app theme preference; Resolve(mode) -> palette. |
WindowChrome |
Low-level DWM dark title bar (Apply(form, dark), SetDarkTitleBar(handle, dark)). |
- Augment, not replace. Standard controls are recolored via their properties;
Buttons use
FlatStyle.Flat, DataGridView usesEnableHeadersVisualStyles = false. Unknown/third-party controls get container-level colors and are otherwise untouched. - Pattern-match ordering. Derived control types (e.g.
LinkLabel : Label) are matched before their bases so each gets the right treatment. - Graceful degradation. The dark title bar is best-effort: on Windows versions that don't support the DWM attribute, theming still recolors the client area.
dotnet build
dotnet test
Multi-targets net462 and net8.0-windows. The 11 tests cover palette definitions,
OS-preference interpretation, and ThemeApplier recoloring real control trees.
samples/WinControls.Demo is a form full of standard controls with a Light/Dark/
System switcher, showing in-place theming and the native title bar.
- Owner-drawn scrollbars and a dark context-menu renderer.
- Opt-in flat tab and toolstrip renderers.
MIT. See LICENSE.