Complete control guide
Siticone Form
SiticoneForm is a borderless WinForms Form with a themed title bar,
DPI-aware control-box glyphs, edge resizing, drag-to-edge snapping, placement persistence,
system-theme integration, optional Windows 11 backdrops, closing safeguards, and fade animation.
This guide documents the complete public API shown in the supplied control source.
Follow the Windows app theme, use the Windows accent color, detect platform support, and opt into Mica, Acrylic, or Mica Alt.
The borderless window retains familiar edge resizing, title-bar dragging, working-area maximize behavior, and seven useful snap destinations.
Close, maximize, minimize, help, pin, and settings buttons have independent visibility, glyph sizing, and normal, hover, and pressed colors.
The control derives from System.Windows.Forms.Form. You can continue to add controls in the
Visual Studio designer and use ordinary inherited members such as ShowDialog(),
DialogResult, Owner, Shown, and FormClosed.
The deliberate exceptions are listed in Compatibility members.
Quick start
Change the base class of an existing WinForms window from Form to SiticoneForm.
Keep InitializeComponent() exactly where the designer generated it.
using SiticoneNetFrameworkUI;
public partial class MainWindow : SiticoneForm
{
public MainWindow()
{
InitializeComponent();
FormTitle = "My application";
StartPosition = FormStartPosition.CenterScreen;
}
}
A practical first configuration
This keeps the familiar window actions, hides optional buttons until they are useful, and leaves DPI scaling enabled.
public MainWindow()
{
InitializeComponent();
FormTitle = "Dashboard";
ShowCloseBox = true;
ShowMaximizeBox = true;
ShowMinimizeBox = true;
ShowHelpBox = false;
ShowPinToTopBox = false;
ShowSettingsBox = false;
DragTitleBar = true;
EnableFormResizing = true;
EnableDpiScaling = true;
MaximizeToWorkingArea = true;
}
Important constructor defaults
These values are applied by a new SiticoneForm() before your form-specific configuration runs.
| Area | Initial value | What it means |
|---|---|---|
| Border | FormBorderStyle.None | The custom title bar replaces the standard Windows caption and border. |
| Start position | CenterScreen | The first show is centered unless you select another StartPosition or restore saved placement. |
| Theme | FormThemeVariant.LightDefault | The theme engine applies its light default colors at construction. |
| Scaling | AutoScaleMode.Dpi | The form and its custom chrome are prepared for per-display DPI scaling. |
| Application font | Segoe UI, 9pt, Regular | Inherited Font is initialized for ordinary form content. |
| Title font | Segoe UI, 9pt, Bold | FormTitleFont controls the title text independently. |
| All six title-bar buttons | Visible | Hide Help, Pin, or Settings if your application does not use their events. |
| Fade and shadow | Enabled | The normal fade duration is 160 ms and the native drop-shadow switch is on. |
| Dragging and resizing | Enabled | The title bar drags the form and a 6 logical-pixel edge grip resizes it. |
| Snapping | Enabled | Edge snapping, snap preview, and restore-on-drag behavior are enabled. |
| Closing safeguards | Disabled | Confirmation, countdown, and closing prevention are opt-in. |
| Windows 11 backdrop | Disabled / None | The form paints an ordinary opaque themed surface until enabled. |
FormTitle updates both the custom title text and the underlying window text.
The inherited-looking Text member remains public for compatibility, but it is hidden from the designer
and setting it directly does not update the custom title field.
Themes and manual colors
The theme engine owns the form surface, title bar, six control-box buttons, legacy hover colors, and snap-preview accent until you manually customize an individual color. A manual color remains in place during ordinary theme refreshes unless you explicitly reset customization.
Select a theme supplied by your installed package
FormThemeVariant is defined by the library's form-theme helper. The supplied SiticoneForm
source proves LightDefault as the default. Use IntelliSense to choose any additional variant available
in the exact package version referenced by your application.
private void ChangeTheme(FormThemeVariant selectedTheme)
{
// ApplyTheme clears manual color flags first, then applies the variant.
ApplyTheme(selectedTheme);
}
private void RestoreDocumentedDefaultTheme()
{
ApplyTheme(FormThemeVariant.LightDefault);
}
Choose the correct refresh method
| Member | Preserves custom colors? | Use it when |
|---|---|---|
| RefreshTheme() | Yes | You want the current variant reapplied only to properties that the application has not manually customized. |
| ApplyTheme(variant) | No | You want the chosen variant to take full control of every theme-managed color immediately. |
| ResetColorCustomizations() | Clears the flags | You want to return ownership to the theme engine. Call RefreshTheme() afterward to repaint with the current theme. |
| RefreshAppearance() | Yes | You changed chrome sizing or visibility in a batch and want metrics, buttons, and painting refreshed; it does not select a theme. |
private void UseThemeColorsAgain()
{
ResetColorCustomizations();
RefreshTheme();
}
Keep a custom form background while themes change
Set BackColorCustomizable before assigning BackColor. This explicitly exempts the form
surface from theme painting while the title bar and buttons may continue to follow ThemeVariant.
BackColorCustomizable = true;
BackColor = Color.FromArgb(18, 20, 42);
// The title bar and control-box colors can still use the selected theme.
RefreshTheme();
ForceThemeBackColorOverride defaults to true. When ThemeVariant changes,
it clears manual BackColor and ForeColor customization flags so the new variant can apply.
BackColorCustomizable is the stronger, explicit exemption for the background.
Turn the theme engine off for a completely manual design
EnableThemeEngine = false;
BackColor = Color.FromArgb(20, 22, 28);
ForeColor = Color.White;
TitleBarBackColor = Color.FromArgb(12, 14, 19);
TitleBarForeColor = Color.White;
CloseButtonBackColor = Color.Transparent;
CloseButtonHoverBackColor = Color.FromArgb(190, 35, 45);
CloseButtonHoverForeColor = Color.White;
RefreshAppearance();
Windows theme and accent color
FollowSystemTheme switches between SystemLightThemeVariant and
SystemDarkThemeVariant when the Windows app preference changes. The light choice defaults to
LightDefault. The dark choice resolves a variant named DarkDefault when that value exists
in the installed enum and otherwise falls back to LightDefault.
public MainWindow()
{
InitializeComponent();
FollowSystemTheme = true;
UseSystemAccentColor = true;
}
private void refreshThemeButton_Click(object sender, EventArgs e)
{
// Useful after your own settings workflow changes Windows-related options.
SyncWithSystemTheme();
}
SiticoneForm.IsSystemInDarkMode()
Returns whether Windows currently requests dark app mode. If the preference cannot be read, it safely returns false.
AccentColor
Returns the Windows accent when UseSystemAccentColor is true; otherwise it returns the theme-driven snap accent.
private void ShowThemeStatus()
{
bool windowsUsesDarkApps = SiticoneForm.IsSystemInDarkMode();
bool formLooksDark = IsDarkTheme;
Color effectiveAccent = AccentColor;
statusLabel.Text =
"Windows dark: " + windowsUsesDarkApps +
"; Form dark: " + formLooksDark +
"; Accent: " + effectiveAccent;
}
Windows 11 backdrops
Backdrops are opt-in and require Windows build 22621 or newer. Set both EnableBackdrop = true
and a non-None BackdropType. Earlier Windows versions safely continue without the material.
| FormBackdropType | Numeric value | Meaning |
|---|---|---|
| None | 0 | No system material; the form paints its own opaque background. |
| Auto | 1 | Lets Windows choose the material. |
| Mica | 2 | Uses the wallpaper-tinted main-window Mica material. |
| Acrylic | 3 | Uses the transient-window Acrylic material. |
| MicaAlt | 4 | Uses the tabbed-window Mica variant. |
private void ConfigureBackdrop()
{
if (SiticoneForm.IsBackdropSupported)
{
EnableFadeAnimation = false;
EnableBackdrop = true;
BackdropType = FormBackdropType.Mica;
AutoBackdropBackColor = true;
}
else
{
EnableBackdrop = false;
BackdropType = FormBackdropType.None;
RefreshTheme();
}
}
A DWM backdrop and a layered, partially transparent window are incompatible. The form skips its startup fade
while a backdrop is active. For a predictable configuration, set EnableFadeAnimation = false
whenever you enable a backdrop.
private void SetBackdrop(FormBackdropType material)
{
bool supported = SiticoneForm.IsBackdropSupported;
EnableFadeAnimation = !supported || material == FormBackdropType.None;
EnableBackdrop = supported && material != FormBackdropType.None;
BackdropType = supported ? material : FormBackdropType.None;
}
private void ShowBackdropStatus()
{
statusLabel.Text = IsBackdropActive
? "System backdrop enabled"
: "Opaque themed background";
}
Title bar, icon and DPI
Title-bar measurements and control-box glyph measurements are logical values based on a 96-DPI design baseline.
With EnableDpiScaling = true, the control scales them for the current display. The title icon is rendered
from the best available icon frame for the required physical size.
FormTitle = "Patient dashboard";
FormTitleFont = new Font("Segoe UI", 10f, FontStyle.Bold);
TitleBarHeight = 42;
TitleLeftPadding = 12;
Icon = Properties.Resources.ApplicationIcon;
IconSize = 22;
ShowTitleBarIcon = true;
ShowTitleBarText = true;
Create an icon-only or text-only caption
private void UseTextOnlyCaption()
{
ShowTitleBarIcon = false;
ShowTitleBarText = true;
}
private void UseIconOnlyCaption()
{
ShowTitleBarIcon = true;
ShowTitleBarText = false;
}
Tune control-box dimensions for your design
EnableDpiScaling = true;
TitleBarHeight = 40;
ControlBoxButtonWidth = 56;
IconSize = 21;
CloseButtonIconSize = 5.5f;
MaximizeButtonIconSize = 5.5f;
MinimizeButtonIconSize = 5.5f;
HelpButtonIconSize = 2.9f;
PinButtonIconSize = 5.5f;
SettingsButtonIconSize = 5.5f;
ControlBoxIconStrokeWidth = 1.8f;
RefreshAppearance();
DpiScaleFactor is DeviceDpi / 96 while DPI scaling is enabled and 1
when it is disabled. You normally do not multiply the documented logical size properties yourself.
Control box
The title bar contains six independently visible buttons. Close, maximize, minimize, and pin perform their actions automatically. Help and Settings intentionally expose events so your application decides what to open.
| Button | Visibility property | Built-in behavior |
|---|---|---|
| Close | ShowCloseBox | Runs the configured countdown or confirmation behavior, raises the applicable close event, and begins the close sequence. |
| Maximize / Restore | ShowMaximizeBox | Calls ToggleMaximizeState(). |
| Minimize | ShowMinimizeBox | Sets WindowState to Minimized. |
| Help | ShowHelpBox | Raises HelpButtonClicked; your handler opens the relevant help experience. |
| Pin to top | ShowPinToTopBox | Toggles IsPinned and TopMost, then raises PinToTopClicked. |
| Settings | ShowSettingsBox | Raises SettingsClicked; your handler opens settings. |
Show only the buttons your application uses
ShowCloseBox = true;
ShowMaximizeBox = true;
ShowMinimizeBox = true;
ShowHelpBox = true;
ShowSettingsBox = true;
ShowPinToTopBox = false;
Connect Help and Settings to your own windows
public MainWindow()
{
InitializeComponent();
ShowHelpBox = true;
ShowSettingsBox = true;
HelpButtonClicked += MainWindow_HelpButtonClicked;
SettingsClicked += MainWindow_SettingsClicked;
}
private void MainWindow_HelpButtonClicked(object sender, EventArgs e)
{
using (HelpWindow help = new HelpWindow())
{
help.ShowDialog(this);
}
}
private void MainWindow_SettingsClicked(object sender, EventArgs e)
{
using (SettingsWindow settings = new SettingsWindow())
{
settings.ShowDialog(this);
}
}
Customize a button for normal, hover, and pressed states
Every button has a foreground property for its glyph and a background property for its surface in each state.
The theme engine treats manual assignments as customizations and leaves them in place during RefreshTheme().
CloseButtonForeColor = Color.FromArgb(220, 225, 232);
CloseButtonBackColor = Color.Transparent;
CloseButtonHoverForeColor = Color.White;
CloseButtonHoverBackColor = Color.FromArgb(190, 35, 45);
CloseButtonPressForeColor = Color.White;
CloseButtonPressBackColor = Color.FromArgb(145, 24, 34);
RotateCloseIconOnHover = true;
Apply one interaction palette to all non-close buttons
private void ApplyControlBoxPalette(Color normal, Color hover, Color pressed)
{
MaximizeButtonForeColor = normal;
MinimizeButtonForeColor = normal;
HelpButtonForeColor = normal;
PinToTopButtonForeColor = normal;
SettingsButtonForeColor = normal;
MaximizeButtonHoverForeColor = hover;
MinimizeButtonHoverForeColor = hover;
HelpButtonHoverForeColor = hover;
PinToTopButtonHoverForeColor = hover;
SettingsButtonHoverForeColor = hover;
MaximizeButtonPressForeColor = pressed;
MinimizeButtonPressForeColor = pressed;
HelpButtonPressForeColor = pressed;
PinToTopButtonPressForeColor = pressed;
SettingsButtonPressForeColor = pressed;
RefreshAppearance();
}
OnHoverControlIconColor and OnHoverControlBackColor update the Maximize,
Minimize, and Help buttons. Pin and Settings have their own legacy aliases, and Close has its own pair.
New code should prefer the explicit per-button state properties.
Dragging, resizing and maximizing
Title-bar dragging
DragTitleBar defaults to true. A small movement threshold distinguishes an intended drag from a
click or double-click, so double-click maximize remains usable when EnableTitleBarDoubleClick is true.
DragTitleBar = true;
EnableTitleBarDoubleClick = true;
EnableFormResizing = true;
ResizeBorderThickness = 6;
MaximizeToWorkingArea = true;
EnableSnapRestoreOnDrag = true;
Drag from passive content surfaces
DragEntireForm adds drag behavior to the form surface and passive descendants that are a
Panel, Label, PictureBox, or GroupBox. Interactive controls such as
buttons, text boxes, lists, and grids retain their normal mouse behavior.
public FloatingSummaryWindow()
{
InitializeComponent();
DragEntireForm = true;
DragTitleBar = true;
EnableFormResizing = false;
}
When enabled, a left-button drag on the form background or supported passive surfaces moves the window. Leave it false if those surfaces implement their own drag selection, drawing, or rearrangement behavior.
Programmatic maximize and restore
public MainWindow()
{
InitializeComponent();
MaximizeStateChanged += MainWindow_MaximizeStateChanged;
}
private void maximizeButton_Click(object sender, EventArgs e)
{
ToggleMaximizeState();
}
private void MainWindow_MaximizeStateChanged(object sender, EventArgs e)
{
layoutPanel.Padding = IsMaximized
? new Padding(16)
: new Padding(24);
}
MaximizeToWorkingArea = true keeps the taskbar visible. If you set it to false, the form clears its
custom maximized bounds and lets Windows use its normal maximize metrics.
Window snapping
Drag snapping uses the working area of the screen under the pointer. The top edge maximizes; the left and right edges use half-screen layouts; corners use quarter-screen layouts. Releasing a drag applies the candidate zone.
| FormSnapZone | Numeric value | Result |
|---|---|---|
| None | 0 | No snap destination is active. |
| Maximize | 1 | Fills the screen working area. |
| Left | 2 | Uses the left half of the working area. |
| Right | 3 | Uses the right half of the working area. |
| TopLeft | 4 | Uses the top-left quarter. |
| TopRight | 5 | Uses the top-right quarter. |
| BottomLeft | 6 | Uses the bottom-left quarter. |
| BottomRight | 7 | Uses the bottom-right quarter. |
Enable or disable snapping independently from its preview
EnableWindowSnapping = true;
EnableSnapRestoreOnDrag = true;
EnableSnapPreview = true;
SnapTriggerDistance = 12;
SnapPreviewCornerRadius = 10;
SnapPreviewBorderThickness = 2;
SnapPreviewOpacity = 0.92d;
SnapPreviewAnimationDuration = 300;
Setting EnableSnapPreview = false hides the visual overlay but does not disable snapping.
Set EnableWindowSnapping = false when the drag itself must never change the window into a snap zone.
Customize the preview
UseSystemAccentColor = false;
SnapPreviewColor = Color.FromArgb(52, 211, 153);
SnapPreviewBorderColor = Color.FromArgb(167, 243, 208);
SnapPreviewCornerRadius = 12;
SnapPreviewBorderThickness = 2;
SnapPreviewOpacity = 0.85d;
SnapPreviewAnimationDuration = 180;
Snap from application commands
private void dockLeftMenuItem_Click(object sender, EventArgs e)
{
SnapTo(FormSnapZone.Left);
}
private void dockBottomRightMenuItem_Click(object sender, EventArgs e)
{
SnapTo(FormSnapZone.BottomRight);
}
private void maximizeMenuItem_Click(object sender, EventArgs e)
{
SnapTo(FormSnapZone.Maximize);
}
SnapTo(FormSnapZone.None) does not restore the window. Use
ToggleMaximizeState() for maximize/restore behavior or assign ordinary bounds for your own layout command.
Resolve a zone without moving the form
private void ShowCandidateZone(Point screenPoint)
{
Rectangle targetBounds;
FormSnapZone zone = ResolveSnapZone(screenPoint, out targetBounds);
if (zone == FormSnapZone.None)
{
statusLabel.Text = "No snap target";
return;
}
statusLabel.Text = zone + " -> " + targetBounds;
}
Observe candidate changes and completed snaps
public MainWindow()
{
InitializeComponent();
SnapZoneChanged += MainWindow_SnapZoneChanged;
Snapped += MainWindow_Snapped;
}
private void MainWindow_SnapZoneChanged(object sender, FormSnapEventArgs e)
{
snapStatusLabel.Text = e.Zone == FormSnapZone.None
? "Move freely"
: "Release to use " + e.Zone;
}
private void MainWindow_Snapped(object sender, FormSnapEventArgs e)
{
snapStatusLabel.Text = "Snapped to " + e.Zone + " at " + e.Bounds;
}
Save and restore window placement
SaveWindowPlacement() returns a compact, culture-independent string containing normal bounds and
maximized state. RestoreWindowPlacement() validates the token, honors MinimumSize, rejects
off-screen placement, changes StartPosition to Manual, and returns whether restoration succeeded.
- Create a user-scoped string setting such as
MainWindowPlacement. - Restore it when the form is first shown.
- Save a fresh token when the window closes successfully.
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
string savedPlacement = Properties.Settings.Default.MainWindowPlacement;
if (!RestoreWindowPlacement(savedPlacement))
{
StartPosition = FormStartPosition.CenterScreen;
}
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
Properties.Settings.Default.MainWindowPlacement = SaveWindowPlacement();
Properties.Settings.Default.Save();
base.OnFormClosed(e);
}
Store placement somewhere else
private void RestoreFromProfile(string placementFromProfile)
{
bool restored = RestoreWindowPlacement(placementFromProfile);
if (!restored)
{
StartPosition = FormStartPosition.CenterScreen;
}
}
private string CaptureForProfile()
{
return SaveWindowPlacement();
}
Restoration succeeds only when a meaningful part of the saved window intersects a currently connected screen's working area. Invalid, empty, unknown-version, non-positive-size, and unreachable tokens return false.
Closing safeguards and animation
The custom Close button supports prevention, a click-again-to-cancel countdown, optional confirmation, a cancellable custom event, and an animated close. These options have a defined precedence.
| Situation | What the Close button does | Important detail |
|---|---|---|
PreventFormClosing = true | Does nothing and closing is cancelled. | This is the strongest safeguard and also cancels the eventual framework closing path. |
| A countdown is already active | Stops and clears the countdown. | The second click cancels the pending Close-button request. |
EnableCloseCountdown = true | Starts at CloseCountdownDuration. | When countdown is enabled, the confirmation dialog and custom FormClosing event are not used for that Close-button request. |
| Countdown is off and confirmation is on | Shows the Yes/No confirmation dialog. | Choosing No ends the request. |
| Confirmation accepted or disabled | Raises the custom FormClosing event. | Set CancelEventArgs.Cancel = true to stop this Close-button request. |
| Request is accepted | Runs the close fade when enabled, then closes. | FadeDuration = 0 or EnableFadeAnimation = false makes the transition immediate. |
Ask for confirmation
EnableCloseCountdown = false;
EnableCloseConfirmation = true;
CloseConfirmationTitle = "Close application";
CloseConfirmationMessage = "Are you sure you want to close the application?";
Use a cancellable countdown
EnableCloseCountdown = true;
CloseCountdownDuration = 5;
CloseCountdownFont = new Font("Segoe UI", 10f, FontStyle.Bold);
// The first Close-button click starts the countdown.
// Clicking the Close button again before zero cancels it.
If both EnableCloseCountdown and EnableCloseConfirmation are true, a Close-button click
uses the countdown path. It does not show the confirmation dialog after the countdown reaches zero.
Temporarily block all closing
private async void saveButton_Click(object sender, EventArgs e)
{
PreventFormClosing = true;
try
{
await SaveImportantWorkAsync();
}
finally
{
PreventFormClosing = false;
}
}
Cancel a normal custom Close-button request
public EditorWindow()
{
InitializeComponent();
EnableCloseCountdown = false;
FormClosing += EditorWindow_FormClosing;
}
private void EditorWindow_FormClosing(object sender, CancelEventArgs e)
{
if (!hasUnsavedChanges) return;
DialogResult answer = MessageBox.Show(
this,
"Discard the unsaved changes?",
"Unsaved changes",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
e.Cancel = answer != DialogResult.Yes;
}
It uses CancelEventArgs and is raised by the custom Close button when countdown is disabled and
confirmation has been accepted. It is not raised by the countdown reaching zero or by the public
Close() method. Use inherited FormClosed when you need notification after every successful close.
Close from code
private void exitAfterSaveButton_Click(object sender, EventArgs e)
{
// Starts the Siticone close sequence directly.
// It does not display the configured countdown or confirmation dialog.
Close();
}
Configure fade timing
EnableFadeAnimation = true;
FadeDuration = 140;
// Valid assignments are clamped between 0 and 5000 milliseconds.
// Set FadeDuration to 0 for an immediate transition.
Public events
| Event | Event arguments | When it occurs | Recommended use |
|---|---|---|---|
| IsPinnedChanged | IsPinnedChangedEventArgs | After IsPinned changes through its public setter, including a Pin-button toggle. | Persist the new e.IsPinned state or update pin-related UI. |
| MaximizeStateChanged | EventArgs | After the control's maximize/restore workflows change state, including its toggle command, maximize snap, or drag restore. | Reflow UI that should differ between normal and maximized layouts. Directly assigning every possible WindowState value is not documented to raise it. |
| HelpButtonClicked | EventArgs | When the visible Help title-bar button receives a left click. | Open contextual help, documentation, or a support dialog. |
| FormClosing | CancelEventArgs | Before an ordinary custom Close-button request continues, when countdown is disabled and confirmation is accepted. | Cancel that specific request by setting e.Cancel = true. See the closing notes above. |
| PinToTopClicked | EventArgs | After the Pin button toggles IsPinned. | Track that the action came from the button. Read IsPinned for the new state. |
| SettingsClicked | EventArgs | When the visible Settings title-bar button receives a left click. | Open your application's settings window or menu. |
| SnapZoneChanged | FormSnapEventArgs | During a move operation when the candidate zone changes, including a change back to None. | Show text or application UI describing the current candidate. e.Bounds is the proposed target. |
| Snapped | FormSnapEventArgs | After a drag snap or SnapTo() request has been applied. | Persist layout choices or update UI after snapping. |
Pin a utility window and save the state
public UtilityWindow()
{
InitializeComponent();
ShowPinToTopBox = true;
PinToTopPinnedIconColor = Color.DodgerBlue;
IsPinnedChanged += UtilityWindow_IsPinnedChanged;
}
private void UtilityWindow_IsPinnedChanged(object sender, SiticoneForm.IsPinnedChangedEventArgs e)
{
Properties.Settings.Default.UtilityWindowPinned = e.IsPinned;
Properties.Settings.Default.Save();
}
Assigning IsPinned also synchronizes TopMost and raises IsPinnedChanged.
Assigning TopMost synchronizes the pin state and glyph, but its setter does not raise
IsPinnedChanged. Prefer IsPinned when event notification matters.
Complete public property reference
The following tables document every public property declared by the supplied SiticoneForm source,
including designer-hidden, read-only, compatibility, and legacy members. “Theme-managed” means the effective
initial color comes from FormThemeVariant.LightDefault; the source does not hard-code that provider's
public palette into the property contract.
Theme, surface and Windows appearance
| Property | Type | Default / range | Purpose and usage |
|---|---|---|---|
| ThemeVariant | FormThemeVariant | LightDefault | Selects the library theme used for non-customized form, title-bar, control-box, and snap-accent colors.ThemeVariant = FormThemeVariant.LightDefault; |
| EnableThemeEngine | bool | true | When false, theme application stops changing colors so your assignments remain fully manual.EnableThemeEngine = false; |
| BackColor | Color | Theme-managed | Form surface color. A manual assignment is tracked as a customization.BackColor = Color.FromArgb(18, 20, 42); |
| ForeColor | Color | Theme-managed | Form foreground color. A manual assignment is tracked as a customization.ForeColor = Color.White; |
| BackColorCustomizable | bool | false | Explicitly exempts BackColor from theme painting. Setting it back to false returns the surface to the theme.BackColorCustomizable = true; |
| ForceThemeBackColorOverride | bool | true | When ThemeVariant changes, clears manual BackColor and ForeColor flags so the new theme can apply.ForceThemeBackColorOverride = false; |
| FollowSystemTheme | bool | false | Automatically chooses the configured light or dark variant as the Windows app theme changes.FollowSystemTheme = true; |
| SystemLightThemeVariant | FormThemeVariant | LightDefault | Variant selected when Windows requests light apps and FollowSystemTheme is enabled. |
| SystemDarkThemeVariant | FormThemeVariant | DarkDefault when available; otherwise LightDefault | Variant selected when Windows requests dark apps and FollowSystemTheme is enabled. |
| UseSystemAccentColor | bool | false | Uses the Windows personalization accent for accent-driven colors such as the snap preview.UseSystemAccentColor = true; |
| EnableBackdrop | bool | false | Master switch for a supported Windows 11 system backdrop. A non-None BackdropType is also required. |
| BackdropType | FormBackdropType | None | Selects Auto, Mica, Acrylic, MicaAlt, or None. Requires Windows build 22621 or newer.BackdropType = FormBackdropType.Mica; |
| AutoBackdropBackColor | bool | true | When a backdrop is active, manages the form surface needed for the DWM material. Disable only when you deliberately manage the backdrop surface yourself. |
| UseRoundedCorners | bool | true | Requests rounded window corners on Windows 11. Earlier Windows versions ignore the request safely. |
| EnableDropShadow | bool | true | Controls the native drop-shadow window style. Configure it before handle creation for a predictable result. |
| ForceDropshadow | bool | false | Keeps the focused border/shadow visual treatment while inactive, removing the usual active/inactive visual distinction. |
Title bar, icon, layout and DPI
| Property | Type | Default / range | Purpose and usage |
|---|---|---|---|
| FormTitle | string | "Form Title" | Visible custom caption. Also updates the underlying window text and taskbar caption.FormTitle = "Dashboard"; |
| FormTitleFont | Font | Segoe UI, 9pt, Bold | Font used only for the custom caption text. |
| TitleBarBackColor | Color | Theme-managed | Fills the custom title-bar area. Manual assignment becomes a preserved customization. |
| TitleBarForeColor | Color | Theme-managed | Color used to draw FormTitle. |
| TitleLeftPadding | int | 10 logical px | Space from the left window edge to the title-bar icon or text. |
| TitleBarHeight | int | 36 logical px; minimum 1 | Height shared by the title-bar surface and control-box buttons.TitleBarHeight = 42; |
| ShowTitleBarIcon | bool | true | Shows or hides the custom title-bar icon without changing the taskbar icon. |
| ShowTitleBarText | bool | true | Shows or hides the custom caption text. |
| Icon | Icon | null until assigned | Sets the image used by the title bar and standard taskbar integration. Multi-size icon resources give the best high-DPI result. |
| IconSize | int | 21 logical px; minimum 1 | Logical size of the icon in the title bar. |
| ControlBoxButtonWidth | int | 59 logical px; minimum 1 | Width applied to every visible title-bar button. |
| EnableDpiScaling | bool | true | Scales title-bar height, button width, icon sizes, glyph stroke, resize grip, and other logical chrome metrics for the display DPI. |
| StartPosition | FormStartPosition | CenterScreen | Controls the initial position. Successful placement restoration changes it to Manual. |
| EnableTitleBarDoubleClick | bool | true | Lets a left-button title-bar double-click call ToggleMaximizeState(). |
Window interaction, state and pinning
| Property | Type | Default / range | Purpose and usage |
|---|---|---|---|
| DragTitleBar | bool | true | Enables dragging from the custom caption area. |
| DragEntireForm | bool | false | Also enables dragging from the form background and passive Panel, Label, PictureBox, and GroupBox descendants. |
| EnableFormResizing | bool | true | Enables edge and corner resizing while the form is in its normal state. |
| ResizeBorderThickness | int | 6 logical px; minimum 1 | Thickness of the invisible resize grip along all edges. |
| MaximizeToWorkingArea | bool | true | Uses the current screen working area when maximizing so the taskbar remains visible. |
| EnableSnapRestoreOnDrag | bool | true | Dragging a snapped window away restores its pre-snap size under the pointer. |
| TopMost | bool | false | Keeps the window above non-topmost windows and synchronizes the pin state. |
| IsPinned | bool | false | Pin-oriented wrapper around TopMost. Its setter raises IsPinnedChanged when the value changes. |
| PinToTopPinnedIconColor | Color | Theme-managed | Glyph color used while IsPinned is true. |
Snapping and preview
| Property | Type | Default / range | Purpose and usage |
|---|---|---|---|
| EnableWindowSnapping | bool | true | Allows edge and corner zones to be applied when a drag is released. |
| EnableSnapPreview | bool | true | Shows the visual candidate overlay. Turning it off leaves snap behavior enabled. |
| SnapTriggerDistance | int | 12 logical px; minimum 1 | Distance from a working-area edge at which a zone becomes active. |
| SnapPreviewColor | Color | Theme-managed accent | Base fill/accent color of the preview. Manual assignment is preserved across ordinary theme refreshes. |
| SnapPreviewBorderColor | Color | Theme-managed light accent | Outline color of the preview. Manual assignment is preserved across ordinary theme refreshes. |
| SnapPreviewCornerRadius | int | 10 logical px; minimum 0 | Corner radius of the preview overlay. |
| SnapPreviewBorderThickness | int | 2 logical px; minimum 0 | Configured outline thickness of the preview. |
| SnapPreviewOpacity | double | 0.92; clamped 0..1 | Peak opacity of the preview overlay. |
| SnapPreviewAnimationDuration | int | 300 ms; clamped 0..2000 | Preview fade duration. Zero makes it appear and disappear immediately. |
Control-box visibility and glyph sizing
| Property | Type | Default / range | Purpose and usage |
|---|---|---|---|
| ShowMaximizeBox | bool | true | Shows the Maximize/Restore button. |
| ShowMinimizeBox | bool | true | Shows the Minimize button. |
| ShowHelpBox | bool | true | Shows the Help button that raises HelpButtonClicked. |
| ShowCloseBox | bool | true | Shows the custom Close button. |
| ShowPinToTopBox | bool | true | Shows the Pin button. |
| ShowSettingsBox | bool | true | Shows the Settings button that raises SettingsClicked. |
| CloseButtonIconSize | float | 5; only values > 0 accepted | Logical radius of the Close glyph. |
| MaximizeButtonIconSize | float | 5; only values > 0 accepted | Logical half-width of the Maximize/Restore glyph. |
| MinimizeButtonIconSize | float | 5; only values > 0 accepted | Logical half-width of the Minimize glyph. |
| HelpButtonIconSize | float | 2.7; only values > 0 accepted | Logical size used to construct the Help glyph. |
| PinButtonIconSize | float | 5; only values > 0 accepted | Logical size of the Pin glyph. |
| SettingsButtonIconSize | float | 5; only values > 0 accepted | Logical size of the Settings glyph. |
| ControlBoxIconStrokeWidth | float | 1.8; only values > 0 accepted | Logical line thickness shared by the vector control-box glyphs. |
Closing and animation
| Property | Type | Default / range | Purpose and usage |
|---|---|---|---|
| PreventFormClosing | bool | false | Cancels form closing and makes the custom Close button ignore clicks while true. |
| EnableCloseCountdown | bool | false | First Close-button click starts a countdown; a second click while active cancels it. |
| CloseCountdownDuration | int | 5 seconds; minimum 1 | Starting value displayed by the Close-button countdown. |
| CloseCountdownFont | Font | Segoe UI, 9pt, Bold | Font used for the countdown digits inside the Close button. |
| EnableCloseConfirmation | bool | false | Shows a Yes/No dialog for Close-button requests when countdown is disabled. |
| CloseConfirmationTitle | string | "Confirm Close" | Title of the built-in confirmation dialog. |
| CloseConfirmationMessage | string | "Are you sure you want to close the application?" | Message of the built-in confirmation dialog. |
| EnableFadeAnimation | bool | true | Enables fade-in when shown and fade-out during the Siticone close sequence. Disable for backdrop configurations. |
| FadeDuration | int | 160 ms; clamped 0..5000 | Duration used by both fade directions. Zero makes the transition immediate. |
| RotateCloseIconOnHover | bool | false | Animates the Close glyph while the pointer hovers over it. |
Per-button state colors
All 36 properties below are theme-managed initially. Assigning one property preserves that specific state color
through RefreshTheme(). Use ApplyTheme(variant) when you want a theme to reclaim all of them.
Close button
| State | Glyph property | Background property |
|---|---|---|
| Normal | CloseButtonForeColor | CloseButtonBackColor |
| Hover | CloseButtonHoverForeColor | CloseButtonHoverBackColor |
| Pressed | CloseButtonPressForeColor | CloseButtonPressBackColor |
Maximize / Restore button
| State | Glyph property | Background property |
|---|---|---|
| Normal | MaximizeButtonForeColor | MaximizeButtonBackColor |
| Hover | MaximizeButtonHoverForeColor | MaximizeButtonHoverBackColor |
| Pressed | MaximizeButtonPressForeColor | MaximizeButtonPressBackColor |
Minimize button
| State | Glyph property | Background property |
|---|---|---|
| Normal | MinimizeButtonForeColor | MinimizeButtonBackColor |
| Hover | MinimizeButtonHoverForeColor | MinimizeButtonHoverBackColor |
| Pressed | MinimizeButtonPressForeColor | MinimizeButtonPressBackColor |
Help button
| State | Glyph property | Background property |
|---|---|---|
| Normal | HelpButtonForeColor | HelpButtonBackColor |
| Hover | HelpButtonHoverForeColor | HelpButtonHoverBackColor |
| Pressed | HelpButtonPressForeColor | HelpButtonPressBackColor |
Pin-to-top button
| State | Glyph property | Background property |
|---|---|---|
| Normal | PinToTopButtonForeColor | PinToTopButtonBackColor |
| Hover | PinToTopButtonHoverForeColor | PinToTopButtonHoverBackColor |
| Pressed | PinToTopButtonPressForeColor | PinToTopButtonPressBackColor |
Settings button
| State | Glyph property | Background property |
|---|---|---|
| Normal | SettingsButtonForeColor | SettingsButtonBackColor |
| Hover | SettingsButtonHoverForeColor | SettingsButtonHoverBackColor |
| Pressed | SettingsButtonPressForeColor | SettingsButtonPressBackColor |
Legacy control-box aliases
These public aliases remain usable for existing designer files. Prefer the explicit properties in the right column for new code.
| Legacy property | Maps to | Exact scope |
|---|---|---|
| OnHoverPinToTopIconColor | PinToTopButtonHoverForeColor | Pin hover glyph. |
| OnHoverPinToTopBackColor | PinToTopButtonHoverBackColor | Pin hover background. |
| OnHoverSettingsIconColor | SettingsButtonHoverForeColor | Settings hover glyph. |
| OnHoverSettingsBackColor | SettingsButtonHoverBackColor | Settings hover background. |
| OnHoverCloseIconColor | CloseButtonHoverForeColor | Close hover glyph. |
| OnHoverCloseButtonBackColor | CloseButtonHoverBackColor | Close hover background. |
| OnHoverControlIconColor | Maximize, Minimize and Help hover foreground properties | Updates those three glyph colors together; it does not update Close, Pin, or Settings. |
| OnHoverControlBackColor | Maximize, Minimize and Help hover background properties | Updates those three backgrounds together; it does not update Close, Pin, or Settings. |
Read-only, hidden and compatibility properties
| Property | Type | Access / value | Purpose and important behavior |
|---|---|---|---|
| DpiScaleFactor | float | Read only; 1 at 96 DPI or when scaling is off | Current chrome scale relative to the 96-DPI design baseline. |
| IsMaximized | bool | Read only | True for either the standard maximized state or the control's tracked manual maximize state. |
| FormBorderStyle | FormBorderStyle | Always None | Hidden from the designer. Assignments are forced back to FormBorderStyle.None because the control supplies its own chrome. |
| Text | string | Hidden compatibility member | Sets the underlying window text but not the custom FormTitle field. Use FormTitle for the visible custom caption. |
| IsWindows11 | static bool | Read only | True when the detected Windows build is at least 22000. |
| IsBackdropSupported | static bool | Read only | True when the detected Windows build is at least 22621. |
| SystemAccentColor | static Color | Read only | Current Windows accent, with a safe system-highlight fallback when the platform value is unavailable. |
| AccentColor | Color | Read only | Effective accent after applying UseSystemAccentColor. |
| IsDarkTheme | bool | Read only | Determined from the luminance of the effective form background, not from the variant's name. |
| IsBackdropActive | bool | Read only | True when backdrops are enabled, type is not None, and the detected Windows build supports them. |
| IsCompositionEnabled | bool | Read only | Reports whether desktop window composition was available when the window creation parameters were evaluated. |
| EnableSnapLayouts | bool | false; no effect | Designer-hidden compatibility property retained so older generated code still compiles. Use EnableWindowSnapping; native Windows 11 caption Snap Layouts are not provided by this borderless style. |
Complete public method reference
| Method | Returns | What it does | Typical call |
|---|---|---|---|
| RefreshTheme() | void | Reapplies the current theme to every color that is not marked as manually customized, then updates the window when its handle exists. | RefreshTheme(); |
| ApplyTheme(FormThemeVariant) | void | Clears all manual color customization flags, selects the supplied variant, and applies it immediately. | ApplyTheme(selectedTheme); |
| ResetColorCustomizations() | void | Returns ownership of all theme-managed colors to the theme engine. Call RefreshTheme() | ResetColorCustomizations(); |
| IsSystemInDarkMode() | static bool | Reads the Windows app light/dark preference. Returns false when the preference is unavailable. | bool dark = SiticoneForm.IsSystemInDarkMode(); |
| SyncWithSystemTheme() | void | Re-evaluates the configured Windows theme and accent options, then reapplies backdrop state. | SyncWithSystemTheme(); |
| ResolveSnapZone(Point, out Rectangle) | FormSnapZone | Evaluates a screen-coordinate pointer location and returns its candidate zone plus target bounds without moving the form. | FormSnapZone zone = ResolveSnapZone(point, out bounds); |
| SnapTo(FormSnapZone) | void | Applies a supported zone using the working area of the screen currently hosting the form. None is ignored. | SnapTo(FormSnapZone.Left); |
| SaveWindowPlacement() | string | Serializes normal bounds and maximized state into a compact, culture-independent, versioned token. | string token = SaveWindowPlacement(); |
| RestoreWindowPlacement(string) | bool | Validates and restores a saved token. Returns false for malformed, unsupported, invalid-size, or off-screen data. | bool restored = RestoreWindowPlacement(token); |
| ToggleMaximizeState() | void | Moves between normal and maximized state while retaining normal bounds and raising MaximizeStateChanged. | ToggleMaximizeState(); |
| Close() | void | Starts the Siticone close sequence directly. It bypasses the Close-button countdown, confirmation dialog, and custom FormClosing event. | Close(); |
| RefreshAppearance() | void | Recalculates control-box metrics and visibility, then repaints the control box and form. | RefreshAppearance(); |
Apply user-selected theme and chrome settings together
private void ApplyWindowSettings(
FormThemeVariant theme,
bool showHelp,
bool showSettings,
int titleHeight)
{
ApplyTheme(theme);
ShowHelpBox = showHelp;
ShowSettingsBox = showSettings;
TitleBarHeight = titleHeight;
RefreshAppearance();
}
Public enums and support types
| Type | Public members | Purpose |
|---|---|---|
| SiticoneForm | SiticoneForm() | The enhanced borderless Form documented on this page. |
| FormSnapZone | None, Maximize, Left, Right, TopLeft, TopRight, BottomLeft, BottomRight | Identifies a drag or programmatic snap destination. Values and behavior are listed in Window snapping. |
| FormBackdropType | None, Auto, Mica, Acrylic, MicaAlt | Identifies the requested Windows 11 system material. Values are listed in Windows 11 backdrops. |
| FormSnapEventArgs | FormSnapEventArgs(FormSnapZone zone, Rectangle bounds), Zone, Bounds | Event data for SnapZoneChanged and Snapped. |
| SiticoneForm.IsPinnedChangedEventArgs | IsPinnedChangedEventArgs(bool isPinned), IsPinned | Event data for IsPinnedChanged. |
| SiticoneForm.Margins | Public integer fields: Left, Right, Top, Bottom | Public frame-margin data structure retained for backward compatibility. Normal form configuration does not require it. |
FormSnapEventArgs
| Member | Type | Meaning |
|---|---|---|
| Zone | FormSnapZone | Candidate or completed zone associated with the event. |
| Bounds | Rectangle | Proposed or applied screen bounds. A candidate change to None uses an empty rectangle. |
| FormSnapEventArgs(FormSnapZone, Rectangle) | constructor | Creates event data from a zone and its associated bounds. |
IsPinnedChangedEventArgs
| Member | Type | Meaning |
|---|---|---|
| IsPinned | bool | New pin state after the public IsPinned value changes. |
| IsPinnedChangedEventArgs(bool) | constructor | Creates the event data from the new state. |
It comes from SiticoneNetFrameworkUI.Helpers.FormTheme. This page intentionally does not invent
enum values that were not present in the supplied source. The documented, source-proven default is
FormThemeVariant.LightDefault; select other values through IntelliSense for your installed version.
More complete recipes
Compact modal dialog
public ConfirmationWindow()
{
InitializeComponent();
FormTitle = "Confirm changes";
StartPosition = FormStartPosition.CenterParent;
ShowMaximizeBox = false;
ShowMinimizeBox = false;
ShowHelpBox = false;
ShowPinToTopBox = false;
ShowSettingsBox = false;
ShowCloseBox = true;
EnableFormResizing = false;
EnableTitleBarDoubleClick = false;
EnableWindowSnapping = false;
}
Always-on-top utility window
public NotesWindow()
{
InitializeComponent();
FormTitle = "Quick notes";
ShowPinToTopBox = true;
ShowSettingsBox = false;
ShowHelpBox = false;
ShowMaximizeBox = false;
IsPinned = Properties.Settings.Default.NotesWindowPinned;
}
Fixed-size appliance or kiosk window
EnableFormResizing = false;
EnableWindowSnapping = false;
EnableTitleBarDoubleClick = false;
ShowMaximizeBox = false;
ShowMinimizeBox = false;
MinimumSize = Size;
MaximumSize = Size;
Windows-aware modern window with fallback
private void ConfigureModernWindowsAppearance()
{
FollowSystemTheme = true;
UseSystemAccentColor = true;
UseRoundedCorners = true;
if (SiticoneForm.IsBackdropSupported)
{
EnableFadeAnimation = false;
EnableBackdrop = true;
BackdropType = FormBackdropType.Mica;
}
else
{
EnableBackdrop = false;
BackdropType = FormBackdropType.None;
EnableFadeAnimation = true;
}
SyncWithSystemTheme();
}
Restore placement before the first show
public MainWindow()
{
InitializeComponent();
string placement = Properties.Settings.Default.MainWindowPlacement;
if (!RestoreWindowPlacement(placement))
{
StartPosition = FormStartPosition.CenterScreen;
}
FormClosed += MainWindow_FormClosed;
}
private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.MainWindowPlacement = SaveWindowPlacement();
Properties.Settings.Default.Save();
}
Custom theme with a system-colored snap preview
EnableThemeEngine = false;
BackColor = Color.FromArgb(16, 18, 24);
ForeColor = Color.White;
TitleBarBackColor = Color.FromArgb(8, 10, 14);
TitleBarForeColor = Color.White;
UseSystemAccentColor = true;
SyncWithSystemTheme();
Color accent = AccentColor;
PinToTopPinnedIconColor = accent;
Keyboard commands for common window layouts
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Alt | Keys.Left))
{
SnapTo(FormSnapZone.Left);
return true;
}
if (keyData == (Keys.Control | Keys.Alt | Keys.Right))
{
SnapTo(FormSnapZone.Right);
return true;
}
if (keyData == (Keys.Control | Keys.Alt | Keys.Enter))
{
ToggleMaximizeState();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Apply a batch of visual changes without leaving stale chrome
private void UseCompactChrome()
{
SuspendLayout();
try
{
TitleBarHeight = 34;
ControlBoxButtonWidth = 48;
IconSize = 18;
ShowHelpBox = false;
ShowSettingsBox = false;
}
finally
{
ResumeLayout(true);
RefreshAppearance();
}
}
Troubleshooting and common questions
| Question or symptom | What to check |
|---|---|
| The form looks themed in the designer but uses unexpected colors at runtime. | Confirm the class inherits SiticoneForm, EnableThemeEngine is true, and theme selection occurs after InitializeComponent(). Designer-generated manual color assignments can intentionally remain customized. Call ApplyTheme(ThemeVariant) after initialization when the selected variant must reclaim every color. |
| My manual BackColor is replaced when I switch themes. | Set BackColorCustomizable = true before assigning the background. ForceThemeBackColorOverride defaults to true and normally lets a new variant reclaim BackColor and ForeColor. |
| A custom button color does not change when ThemeVariant changes. | Manual assignments are preserved by design. Use ApplyTheme(newVariant), or call ResetColorCustomizations() followed by RefreshTheme(). |
| The title text did not change after assigning Text. | Assign FormTitle. The compatibility Text property does not update the custom title field. |
| Control-box icons look too small on a high-DPI screen. | Keep EnableDpiScaling = true, use a multi-size Icon, and tune the logical per-button icon-size properties rather than multiplying them by DPI yourself. ControlBoxIconStrokeWidth controls line weight. |
| The Mica or Acrylic material is not visible. | Check SiticoneForm.IsBackdropSupported, set EnableBackdrop = true, select a non-None BackdropType, normally leave AutoBackdropBackColor = true, and disable fade animation. |
| The native Windows 11 Snap Layouts flyout does not appear. | This control uses a borderless style. EnableSnapLayouts is a no-effect compatibility property. Use EnableWindowSnapping for the control's drag-to-edge and corner layouts. |
| Snapping works but no preview appears. | Set EnableSnapPreview = true. Preview visibility and actual snapping are separate switches. |
| The confirmation dialog does not appear. | EnableCloseCountdown takes precedence. Also, calling the public Close() method starts the close sequence directly rather than running Close-button confirmation. |
| My custom FormClosing handler is not called after a countdown or Close(). | This is the documented scope of the custom shadowing event. Disable countdown for that Close-button event, or use inherited FormClosed for notification after every successful close. |
| IsPinnedChanged did not fire when I assigned TopMost. | Assign IsPinned when you need IsPinnedChanged. The TopMost setter synchronizes state and visuals without raising that custom event. |
| A saved placement is ignored. | The token must come from SaveWindowPlacement(), contain a valid positive size, use the supported version, and remain meaningfully visible on a connected monitor. Treat a false return as a request to use your normal StartPosition. |
| The border cannot be changed from None. | This is intentional. FormBorderStyle is forced to None because SiticoneForm supplies the title bar, control box, resizing, shadow, and window interaction itself. |
Runtime theme recovery pattern
public MainWindow()
{
InitializeComponent();
FormThemeVariant selectedTheme = ThemeVariant;
ApplyTheme(selectedTheme);
}
private void restoreThemeButton_Click(object sender, EventArgs e)
{
ResetColorCustomizations();
RefreshTheme();
}
Use ThemeVariant or RefreshTheme() when custom colors should survive. Use
ApplyTheme(variant) when the theme must replace every custom color. Use
RefreshAppearance() when dimensions or visibility changed but the selected theme did not.