Complete control guide
Siticone Left Sidebar
SiticoneLeftSidebar is a WinForms navigation panel with built-in expand and collapse animation,
icon-rail navigation, tooltips, overlay drawers, outside-click handling, resizable width, state persistence,
keyboard navigation, DPI scaling, left or right docking, and optional header/content/footer regions.
This guide covers every public member introduced by the sidebar API and shows how the features work together.
The sidebar owns its expand/collapse behavior. Assign ToggleControl or call
Expand(), Collapse(), or Toggle(). The control applies
AnimationDuration and AnimationEasing automatically.
The tables below list every public member added by SiticoneLeftSidebar,
SiticoneSidebarItem, their enums, event arguments, rail contract, right-sidebar type,
and conditional design-time types. Standard members inherited unchanged from WinForms
Panel and Control—such as Controls, Dock,
Anchor, BackColor, and Padding—continue to work normally.
Quick start
This complete example creates a left navigation rail, connects a hamburger button, adds bitmap and glyph
items, selects the first item, and switches pages through each item's standard WinForms Tag value.
using SiticoneNetFrameworkUI;
using System;
using System.Drawing;
using System.Windows.Forms;
public partial class MainForm : Form
{
private SiticoneLeftSidebar _sidebar;
private Panel _pageHost;
private Button _menuButton;
public MainForm()
{
InitializeComponent();
BuildNavigation();
}
private void BuildNavigation()
{
_menuButton = new Button();
_menuButton.Text = "Menu";
_menuButton.Dock = DockStyle.Top;
_pageHost = new Panel();
_pageHost.Dock = DockStyle.Fill;
_sidebar = new SiticoneLeftSidebar();
_sidebar.Name = "mainSidebar";
_sidebar.SidebarSide = SiticoneSidebarSide.Left;
_sidebar.ExpandedWidth = 260;
_sidebar.CollapsedWidth = 64;
_sidebar.EnableIconRailMode = true;
_sidebar.EnableCollapsedToolTips = true;
_sidebar.AnimationDuration = 220;
_sidebar.AnimationEasing = SiticoneSidebarEasing.EaseInOut;
_sidebar.ToggleControl = _menuButton;
Controls.Add(_pageHost);
Controls.Add(_sidebar);
Controls.Add(_menuButton);
SiticoneSidebarItem dashboard = _sidebar.AddItem("Dashboard", Properties.Resources.DashboardIcon);
dashboard.Tag = "Dashboard";
SiticoneSidebarItem patients = _sidebar.AddItem("Patients", Properties.Resources.PatientsIcon);
patients.Tag = "Patients";
Font glyphFont = new Font("Segoe MDL2 Assets", 16f, FontStyle.Regular);
SiticoneSidebarItem settings = _sidebar.AddGlyphItem("Settings", "\uE713", glyphFont, null);
settings.Tag = "Settings";
_sidebar.ItemClicked += Sidebar_ItemClicked;
_sidebar.SelectItem(dashboard);
ShowPage("Dashboard");
}
private void Sidebar_ItemClicked(object sender, SiticoneSidebarItemEventArgs e)
{
string pageKey = e.ItemTag as string;
if (!string.IsNullOrEmpty(pageKey))
{
ShowPage(pageKey);
}
}
private void ShowPage(string pageKey)
{
_pageHost.Controls.Clear();
Label page = new Label();
page.Text = pageKey;
page.Dock = DockStyle.Fill;
page.TextAlign = ContentAlignment.MiddleCenter;
_pageHost.Controls.Add(page);
}
}
A custom GlyphFont is supplied by your application. If several items share one font, keep it
as a form field and dispose it with the form rather than creating a separate font for every item.
The remaining snippets use sidebar for a SiticoneLeftSidebar field and names such as
dashboardItem for existing SiticoneSidebarItem fields. Replace those names with the
designer-generated or programmatic names in your form. Resource icons are examples; use your own images.
Designer-first setup
- Drag
SiticoneLeftSidebarfrom the Toolbox onto the form. - Set
ExpandedWidthandCollapsedWidth. The defaults are 240 and 56 pixels. - Assign your hamburger button to
ToggleControl; do not add a second click handler that callsToggle(). - Drop
SiticoneSidebarItemcontrols into the sidebar, or add them in code withAddItem. - Enable only the optional behaviors your layout needs: rail, scrim, resizing, persistence, keyboard, or regions.
private void MainForm_Load(object sender, EventArgs e)
{
siticoneLeftSidebar1.ExpandedWidth = 260;
siticoneLeftSidebar1.CollapsedWidth = 60;
siticoneLeftSidebar1.ToggleControl = menuButton;
siticoneLeftSidebar1.EnableIconRailMode = true;
siticoneLeftSidebar1.EnableCollapsedToolTips = true;
siticoneLeftSidebar1.SelectIndex(0);
}
Core concepts
State reports the runtime state. IsExpanded is the requested stable state; IsAnimating tells you whether a transition is still running.
ExpandedWidth is the open width. CollapsedWidth is the closed width and may be zero for a fully closed sidebar.
With EnableIconRailMode, items hide captions at the rail threshold, center or left-align icons, and turn visible badges into compact dots.
Combine BringToFrontOnExpand, a scrim, outside-click closing, and Escape closing for a modal navigation drawer.
The sidebar derives from Panel. Existing labels, buttons, logos, and custom controls may be docked directly or placed in optional regions.
Rail, scrim, resizing, persistence, keyboard navigation, regions, hover opening, and gradient painting are disabled by default unless listed otherwise.
Constructor defaults inherited from Panel
In addition to the sidebar-specific defaults in the full property tables, a new
SiticoneLeftSidebar() applies these initial standard WinForms values. You may override them normally.
| Inherited property | Initial value | Notes |
|---|---|---|
| Dock | DockStyle.Left | SidebarSide and AutoDock can later mirror it. |
| MinimumSize | 240 x 0 | The sidebar handles narrower collapse targets during its own transitions. |
| BackColor | Color.White | Used when EnableGradient is false. |
| ForeColor | RGB(60,60,60) | Available to hosted content and runtime theme use. |
| Padding | 5,5,20,5 | Includes the initial right-side shadow reservation for the default left sidebar. |
State and width are related, but not identical
A sidebar is considered logically expanded as soon as an accepted expand request starts. During animation,
its current Width is between the two target widths and State returns
SiticoneSidebarState.Animating. Use the completion events when work must wait for the final size.
private void UpdateSidebarStatus()
{
switch (siticoneLeftSidebar1.State)
{
case SiticoneSidebarState.Expanded:
statusLabel.Text = "Navigation is open";
break;
case SiticoneSidebarState.Collapsed:
statusLabel.Text = "Navigation is collapsed";
break;
case SiticoneSidebarState.Animating:
statusLabel.Text = "Navigation is moving";
break;
}
}
Choose the right collapse style
| Goal | Recommended settings | What users see |
|---|---|---|
| Compact icon navigation | CollapseMode = Width, CollapsedWidth = 56, EnableIconRailMode = true |
A narrow, still-visible strip of icons. |
| Thin empty strip | CollapseMode = Width, HideChildrenWhenCollapsed = true |
The sidebar keeps its collapsed width but its children are temporarily hidden. |
| Collapse to zero | CollapseMode = Width, CollapsedWidth = 0 |
The control remains logically present but has no visible width. |
| Hide the control | CollapseMode = Hide |
The sidebar first reaches CollapsedWidth, then becomes invisible; expanding makes it visible again. |
private void MainForm_Shown(object sender, EventArgs e)
{
siticoneLeftSidebar1.CollapsedWidth = 60;
siticoneLeftSidebar1.EnableIconRailMode = true;
siticoneLeftSidebar1.Collapse(false);
}
private void ConfigureHiddenDrawer()
{
siticoneLeftSidebar1.CollapsedWidth = 0;
siticoneLeftSidebar1.CollapseMode = SiticoneSidebarCollapseMode.Hide;
}
private void closeButton_Click(object sender, EventArgs e)
{
siticoneLeftSidebar1.Collapse();
}
private void openButton_Click(object sender, EventArgs e)
{
siticoneLeftSidebar1.Expand();
}
Visual Studio designer and Smart Tag
On .NET Framework builds, select the sidebar and open its Smart Tag arrow. The design-time menu exposes the
most common properties and actions without requiring code. The runtime control still works on .NET Core and
.NET 5 or later, but the source intentionally compiles these System.Design-based extras only for
non-NETCOREAPP targets.
Preview both sizes and save the current designer width as ExpandedWidth.
Apply a coordinated starting configuration, then adjust individual properties.
These Smart Tag actions set the sidebar background and foreground colors.
Enable the interaction model appropriate for the application.
Tune movement, separation, shape, and monitor scaling.
Reuse browsable, writable appearance and behavior settings on another sidebar.
The design-time action does not copy Name, location, size/bounds, child controls,
ToggleControl, or PersistenceKey. Assign those separately on the destination control.
Navigation items
SiticoneSidebarItem is the companion navigation control. It draws a caption, an optional bitmap
or font glyph, hover/pressed/selected states, a selection indicator, an optional badge, a keyboard focus cue,
and a rail-specific layout. Items dropped below the sidebar register themselves; items created in code are
easiest to manage through the sidebar's AddItem methods.
Add bitmap items
// Caption only.
SiticoneSidebarItem home = sidebar.AddItem("Home");
// Caption and bitmap icon.
SiticoneSidebarItem patients = sidebar.AddItem(
"Patients",
Properties.Resources.PatientsIcon);
// Caption, icon, and click handler.
SiticoneSidebarItem reports = sidebar.AddItem(
"Reports",
Properties.Resources.ReportsIcon,
delegate { OpenReports(); });
Add and fully style an existing item
SiticoneSidebarItem inbox = new SiticoneSidebarItem();
inbox.Text = "Inbox";
inbox.Icon = Properties.Resources.InboxIcon;
inbox.IconSize = new Size(22, 22);
inbox.Height = 48;
inbox.CornerRadius = 8;
inbox.SelectedBackColor = Color.FromArgb(32, 52, 211, 153);
inbox.SelectedForeColor = Color.FromArgb(16, 185, 129);
inbox.IndicatorColor = Color.FromArgb(16, 185, 129);
inbox.ToolTipText = "Open your messages";
inbox.Tag = "InboxPage";
sidebar.AddItem(inbox);
RemoveItem(item) removes, unregisters, and disposes that item.
ClearItems() does the same for every registered item. If an item must remain alive and visible,
call UnregisterItem(item) instead; unregistering stops sidebar tracking but does not remove or
dispose the control. If the item is currently selected and will remain visible, call
ClearSelection() before unregistering so its selected visual state is cleared through the
normal selection lifecycle.
Use an icon-font glyph
A glyph is drawn only when Icon is null. Set Glyph to the character and
GlyphFont to the font that contains it. If GlyphFont is null, the item's
normal Font is used.
private Font _navigationGlyphFont;
private void AddGlyphNavigation()
{
_navigationGlyphFont = new Font("Segoe MDL2 Assets", 17f, FontStyle.Regular);
FormClosed += MainForm_FormClosed;
sidebar.AddGlyphItem("Home", "\uE80F", _navigationGlyphFont, delegate { ShowHome(); });
sidebar.AddGlyphItem("Calendar", "\uE787", _navigationGlyphFont, delegate { ShowCalendar(); });
sidebar.AddGlyphItem("Settings", "\uE713", _navigationGlyphFont, delegate { ShowSettings(); });
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (_navigationGlyphFont != null)
{
_navigationGlyphFont.Dispose();
_navigationGlyphFont = null;
}
}
Show a count or status badge
In the expanded layout, the full BadgeText is displayed. In the collapsed icon rail, a visible,
non-empty badge becomes a small colored dot so it does not crowd the icon.
private SiticoneSidebarItem _inboxItem;
private void CreateInboxItem()
{
_inboxItem = sidebar.AddItem("Inbox", Properties.Resources.InboxIcon);
_inboxItem.BadgeBackColor = Color.Crimson;
_inboxItem.BadgeForeColor = Color.White;
SetUnreadCount(12);
}
private void SetUnreadCount(int unreadCount)
{
_inboxItem.ShowBadge = unreadCount > 0;
_inboxItem.BadgeText = unreadCount > 99 ? "99+" : unreadCount.ToString();
}
Create an action that does not become selected
Set Selectable = false for commands such as Sign out, Help, or New record. The item remains
clickable and keyboard-activatable, but it never replaces the current navigation selection.
SiticoneSidebarItem signOut = sidebar.AddGlyphItem(
"Sign out",
"\uE8AC",
_navigationGlyphFont,
delegate { SignOut(); });
signOut.Selectable = false;
signOut.ToolTipText = "Sign out of this account";
Disable an item temporarily
SiticoneSidebarItem billing = sidebar.AddItem("Billing", Properties.Resources.BillingIcon);
billing.Enabled = false;
billing.DisabledForeColor = Color.FromArgb(145, 145, 145);
billing.ToolTipText = "Billing is not available for your account";
Understand Click, ItemClicked, and Activated
| Event | Best use | Observable behavior |
|---|---|---|
item.Click |
Handle one particular item's normal WinForms click. | Raised for a mouse click and when PerformActivate() invokes the standard click. |
sidebar.ItemClicked |
Handle all registered items from one place. | Includes item, index, text, and tag. A direct mouse click reaches this event before owner selection; PerformActivate() requests selection before it raises the standard click. |
item.Activated |
Observe explicit activation through PerformActivate(). |
Raised by PerformActivate(), including Enter/Space activation; use Click or ItemClicked when mouse clicks must also be observed. |
Selection and page navigation
Only one registered item is selected at a time. For a direct mouse click, the sidebar raises
ItemClicked and then attempts selection. PerformActivate()—used by keyboard activation—
requests selection before it raises the standard click. In either path, an actual selection change raises the
cancellable ItemSelectionChanging event, updates both items, and then raises
ItemSelectionChanged. Use ItemSelectionChanged when navigation must run only after a
successful selection, regardless of activation method.
Select by item or index
// Select a known item.
sidebar.SelectItem(dashboardItem);
// Include a reason in the resulting selection event.
sidebar.SelectItem(dashboardItem, SiticoneSidebarTriggerReason.Code);
// Select the first visible-position item.
sidebar.SelectIndex(0);
// The properties route through the same selection behavior.
sidebar.SelectedItem = patientsItem;
sidebar.SelectedIndex = 2;
// Remove the current selection.
sidebar.ClearSelection();
Passing a negative index or an index outside the current ordered item list to SelectIndex,
or assigning such a value to SelectedIndex, calls ClearSelection().
IndexOfItem(null) and unregistered items return -1.
Switch UserControls using Tag
private void ConfigurePageRouting()
{
dashboardItem.Tag = dashboardPage;
patientsItem.Tag = patientsPage;
settingsItem.Tag = settingsPage;
sidebar.ItemSelectionChanged += Sidebar_ItemSelectionChanged;
}
private void Sidebar_ItemSelectionChanged(
object sender,
SiticoneSidebarSelectionChangedEventArgs e)
{
UserControl page = e.SelectedTag as UserControl;
if (page == null)
{
return;
}
pageHost.Controls.Clear();
page.Dock = DockStyle.Fill;
pageHost.Controls.Add(page);
}
Cancel a selection change
private bool _hasUnsavedChanges;
private void sidebar_ItemSelectionChanging(
object sender,
SiticoneSidebarSelectionChangingEventArgs e)
{
if (!_hasUnsavedChanges)
{
return;
}
DialogResult answer = MessageBox.Show(
"Discard your unsaved changes and leave this page?",
"Unsaved changes",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
e.Cancel = answer != DialogResult.Yes;
}
Refresh dynamically changed items
patientsItem.Text = "People and patients";
patientsItem.ToolTipText = "Open the patient directory";
// Text and ToolTipText already refresh that item's tooltip automatically.
// Call this when several layout-related values changed together.
sidebar.RefreshItems();
// Or explicitly re-evaluate only one tooltip.
sidebar.RefreshItemToolTip(patientsItem);
Icon rail and tooltips
Rail mode becomes active whenever EnableIconRailMode is true and the current sidebar width is at
or below EffectiveRailSwitchWidth. With the default automatic threshold, that value is
CollapsedWidth + 24. Set RailSwitchWidth to a positive value when you need an explicit
threshold.
private void ConfigureIconRail()
{
sidebar.ExpandedWidth = 260;
sidebar.CollapsedWidth = 60;
sidebar.EnableIconRailMode = true;
// Zero means: use CollapsedWidth + 24.
sidebar.RailSwitchWidth = 0;
sidebar.EnableCollapsedToolTips = true;
sidebar.ShowToolTipsWhenExpanded = false;
sidebar.ToolTipInitialDelay = 350;
sidebar.ToolTipAutoPopDelay = 5000;
sidebar.ToolTipReshowDelay = 100;
}
Choose icon alignment per item
dashboardItem.RailIconAlignment = SiticoneSidebarRailIconAlignment.Center;
patientsItem.RailIconAlignment = SiticoneSidebarRailIconAlignment.Center;
brandItem.RailIconAlignment = SiticoneSidebarRailIconAlignment.Left;
Override or suppress a tooltip
An item's explicit ToolTipText wins; when it is empty, the item caption is used. The sidebar's
ItemToolTipShowing event can change the final text or cancel the tooltip for a particular item.
private void sidebar_ItemToolTipShowing(
object sender,
SiticoneSidebarToolTipEventArgs e)
{
if (ReferenceEquals(e.Item, signOutItem))
{
e.Text = "Sign out of " + currentUserName;
}
if (ReferenceEquals(e.Item, decorativeLogoItem))
{
e.Cancel = true;
}
}
Opt out one item
logoItem.ShowToolTipWhenCollapsed = false;
// This can also enable tooltips while the sidebar is open.
sidebar.ShowToolTipsWhenExpanded = true;
Make a custom control rail-aware
Any descendant control implementing ISiticoneSidebarRailAware is notified whenever the rail state
changes. This is useful for a custom brand header, profile block, search control, or footer command.
public sealed class SidebarBrandHeader : UserControl, ISiticoneSidebarRailAware
{
private readonly PictureBox _logo;
private readonly Label _productName;
public SidebarBrandHeader()
{
Height = 64;
Dock = DockStyle.Top;
_logo = new PictureBox();
_logo.Size = new Size(28, 28);
_logo.SizeMode = PictureBoxSizeMode.Zoom;
_productName = new Label();
_productName.Text = "Contoso Health";
_productName.AutoSize = true;
Controls.Add(_logo);
Controls.Add(_productName);
}
public void ApplyRailState(bool railModeEnabled, bool collapsed, int availableWidth)
{
bool showRail = railModeEnabled && collapsed;
_productName.Visible = !showRail;
_logo.Left = showRail
? Math.Max(0, (availableWidth - _logo.Width) / 2)
: 14;
}
}
private void sidebar_RailModeChanged(object sender, SiticoneSidebarRailEventArgs e)
{
railStatusLabel.Text = e.Collapsed
? "Icon rail active at " + e.AvailableWidth + " px"
: "Full navigation active";
}
Overlay drawer, scrim, and outside-click behavior
A drawer normally opens above sibling content, dims the remaining form, and closes when the user clicks the dimmed area, clicks elsewhere, or presses Escape. Each behavior is independently configurable.
private void ConfigureDrawer()
{
sidebar.BringToFrontOnExpand = true;
sidebar.AutoCloseOnOutsideClick = true;
sidebar.AutoCloseOnEscape = true;
sidebar.EnableScrim = true;
sidebar.ScrimColor = Color.Black;
sidebar.ScrimOpacity = 38;
sidebar.ScrimClosesSidebar = true;
sidebar.CollapsedWidth = 0;
sidebar.CollapseMode = SiticoneSidebarCollapseMode.Hide;
sidebar.ToggleControl = menuButton;
}
A click on the dimming overlay raises ScrimClicked. A managed-control click detected outside
the sidebar while AutoCloseOnOutsideClick is enabled raises OutsideClicked.
Cancel the event that matches the interaction you need to protect.
Exclude popups, toolbars, and related controls
ToggleControl is excluded automatically. Use AddOutsideClickException for any other
control that should remain interactive without closing the sidebar. Descendants of an excluded control are
excluded as well, and disposed controls are removed from the exception list automatically.
private void ConfigureOutsideClickExceptions()
{
sidebar.AddOutsideClickException(accountPopup);
sidebar.AddOutsideClickException(topToolbar);
}
private void StopExcludingAccountPopup()
{
sidebar.RemoveOutsideClickException(accountPopup);
}
private void ResetAllExceptions()
{
sidebar.ClearOutsideClickExceptions();
}
Cancel an outside-click close
private void sidebar_OutsideClicked(
object sender,
SiticoneSidebarOutsideClickEventArgs e)
{
if (_mustFinishNavigationTask)
{
e.Cancel = true;
statusLabel.Text = "Finish or cancel the current task before closing navigation.";
}
}
Cancel a scrim close for a specific mouse button
private void sidebar_ScrimClicked(object sender, SiticoneSidebarScrimEventArgs e)
{
if (e.Button != MouseButtons.Left)
{
e.Cancel = true;
}
}
Include title-bar clicks
Non-client clicks such as a window title-bar click are ignored by default. Enable
AutoCloseOnTitleBarClick when those clicks should also close an expanded sidebar.
sidebar.AutoCloseOnOutsideClick = true;
sidebar.AutoCloseOnTitleBarClick = true;
Inspect overlay geometry
Rectangle screenArea = sidebar.CalculateScrimBounds();
if (!screenArea.IsEmpty)
{
debugLabel.Text = string.Format(
"Overlay: {0}, {1}, {2} x {3}",
screenArea.X,
screenArea.Y,
screenArea.Width,
screenArea.Height);
}
Hover-to-expand behavior
Hover mode is useful for desktop icon rails. Entering a collapsed sidebar starts the configured delay;
remaining inside until the delay expires expands it. With CollapseOnMouseLeave enabled, leaving an
expanded sidebar collapses it again.
sidebar.EnableIconRailMode = true;
sidebar.CollapsedWidth = 60;
sidebar.ExpandOnHover = true;
sidebar.HoverExpandDelay = 300;
sidebar.CollapseOnMouseLeave = true;
Do not combine hover-to-expand with a hidden, zero-width sidebar: the user needs a visible area to enter. A collapsed rail between 48 and 72 pixels is a practical hover target.
Right-side navigation
Set SidebarSide = Right, or use SiticoneRightSidebar. The right-side type inherits the
complete API and starts with SidebarSide.Right and DockStyle.Right. Shadow, edge border,
inner corners, resize grip, scrim bounds, and item selection indicators mirror to the opposite edge.
SiticoneRightSidebar inspector = new SiticoneRightSidebar();
inspector.Name = "detailsSidebar";
inspector.ExpandedWidth = 320;
inspector.CollapsedWidth = 0;
inspector.CollapseMode = SiticoneSidebarCollapseMode.Hide;
inspector.EnableScrim = true;
inspector.AutoCloseOnEscape = true;
inspector.BringToFrontOnExpand = true;
Controls.Add(inspector);
Switch sides at runtime
private void MoveSidebarToOppositeSide()
{
sidebar.AutoDock = true;
sidebar.SidebarSide = sidebar.SidebarSide == SiticoneSidebarSide.Left
? SiticoneSidebarSide.Right
: SiticoneSidebarSide.Left;
}
With the default AutoDock = true, assigning SidebarSide also applies the matching
DockStyle. Set AutoDock = false only when your application manages docking itself.
Header, content, and footer regions
Regions create a fixed header, a fill/scroll content area, and a fixed footer. This keeps branding and account
actions visible while a long navigation list scrolls. Enable regions before accessing HeaderPanel,
ContentPanel, or FooterPanel; each getter returns null while regions are disabled.
private void ConfigureSidebarRegions()
{
sidebar.HeaderHeight = 72;
sidebar.FooterHeight = 64;
sidebar.HeaderVisible = true;
sidebar.FooterVisible = true;
sidebar.ContentAutoScroll = true;
sidebar.MoveExistingChildrenToContent = true;
sidebar.EnableRegions = true;
PictureBox logo = new PictureBox();
logo.Image = Properties.Resources.CompanyLogo;
logo.SizeMode = PictureBoxSizeMode.Zoom;
logo.Dock = DockStyle.Fill;
sidebar.HeaderPanel.Controls.Add(logo);
// AddItem uses ItemHost, which is ContentPanel when regions are enabled.
sidebar.AddItem("Dashboard", Properties.Resources.DashboardIcon);
sidebar.AddItem("Patients", Properties.Resources.PatientsIcon);
sidebar.AddItem("Appointments", Properties.Resources.CalendarIcon);
Button accountButton = new Button();
accountButton.Text = "My account";
accountButton.Dock = DockStyle.Fill;
sidebar.FooterPanel.Controls.Add(accountButton);
}
Add controls through ItemHost
ItemHost returns the content region when regions are enabled, otherwise it returns the sidebar.
Use it when reusable setup code must work in both layouts.
Label sectionTitle = new Label();
sectionTitle.Text = "WORKSPACE";
sectionTitle.Height = 32;
sectionTitle.Dock = DockStyle.Top;
sectionTitle.TextAlign = ContentAlignment.MiddleLeft;
sidebar.ItemHost.Controls.Add(sectionTitle);
sectionTitle.BringToFront();
Preserve direct children when enabling regions
// Set this before EnableRegions.
sidebar.MoveExistingChildrenToContent = false;
sidebar.EnableRegions = true;
// Add content explicitly to the intended region.
sidebar.ContentPanel.Controls.Add(customNavigationPanel);
Enabling regions can move existing direct children into the content panel when
MoveExistingChildrenToContent is true. Disabling regions makes the public region getters return
null; it does not serve as a reparenting command for content already placed in those panels.
For a dynamic layout change, move the controls to their new parent deliberately.
Show and hide fixed regions
private void SetCompactNavigation(bool compact)
{
sidebar.HeaderVisible = !compact;
sidebar.FooterVisible = !compact;
}
Appearance, gradient, shadow, border, and themes
The sidebar paints either its standard BackColor or a two-color gradient. It can add rounded
corners, a configurable edge border, and a layered shadow. The terms “right border” remain for backward
compatibility; on a right-side sidebar the edge is drawn on the left. The neutral aliases
EdgeBorderThickness and EdgeBorderColor address the same settings.
Apply a solid runtime theme
ApplyTheme sets only the sidebar's BackColor and ForeColor, invalidates the
control, and raises ThemeApplied. Style individual items separately when their state colors should
match the theme.
private void ApplyDarkNavigationTheme()
{
sidebar.ApplyTheme(
"Dark",
Color.FromArgb(24, 32, 48),
Color.FromArgb(241, 245, 249));
foreach (SiticoneSidebarItem item in sidebar.Items)
{
item.ForeColor = sidebar.ForeColor;
item.HoverBackColor = Color.FromArgb(35, 255, 255, 255);
item.SelectedBackColor = Color.FromArgb(45, 52, 211, 153);
item.SelectedForeColor = Color.FromArgb(110, 231, 183);
item.IndicatorColor = Color.FromArgb(52, 211, 153);
}
}
Paint a gradient
sidebar.EnableGradient = true;
sidebar.GradientStartColor = Color.FromArgb(15, 23, 42);
sidebar.GradientEndColor = Color.FromArgb(30, 41, 59);
sidebar.GradientAngle = 90f;
Configure a soft shadow
sidebar.EnableDropShadow = true;
sidebar.ShadowDepth = 15;
sidebar.ShadowBlur = 40;
sidebar.ShadowSpread = 15;
sidebar.ShadowVerticalOffset = 5;
sidebar.ShadowColor = Color.FromArgb(60, 100, 100, 111);
sidebar.ReserveShadowSpace = true;
sidebar.CacheShadow = true;
Use Color.FromArgb(alpha, red, green, blue). A smaller alpha produces a lighter shadow.
Most shadow-setting changes invalidate the cached bitmap automatically. Call
InvalidateShadowCache() when you deliberately need the next paint to rebuild it.
Keep it enabled when docked child controls must not overlap the shadow edge. If you disable it after
reserved padding has already been applied, set the sidebar's standard WinForms Padding to the
layout you want to reclaim or preserve.
Draw or hide the inner edge border
sidebar.RightBorderVisible = true;
sidebar.EdgeBorderThickness = 1;
sidebar.EdgeBorderColor = Color.FromArgb(71, 85, 105);
// Hide the border without losing its configured thickness or color.
sidebar.RightBorderVisible = false;
RightBorderThickness is clamped to at least 1 pixel. To show no border, set
RightBorderVisible = false; a transparent border color is also accepted.
Round the correct corners
sidebar.CornerRadius = 14;
// Round only the inner/shadow edge: right on a left sidebar,
// and left on a right sidebar.
sidebar.RoundRightCornersOnly = true;
Reset color properties to their documented defaults
sidebar.ResetShadowColor();
sidebar.ResetRightBorderColor();
sidebar.ResetGradientStartColor();
sidebar.ResetGradientEndColor();
sidebar.ResetScrimColor();
sidebar.ResetResizeGripColor();
User resizing
When enabled, users can drag the sidebar's inner edge while it is expanded and not animating. The grip is on
the right for a left sidebar and on the left for a right sidebar. A completed drag updates
ExpandedWidth and can be saved automatically when persistence is active.
sidebar.EnableUserResize = true;
sidebar.MinExpandedWidth = 200;
sidebar.MaxExpandedWidth = 420;
sidebar.ResizeGripSize = 7;
sidebar.ShowResizeCursor = true;
sidebar.ResizeGripColor = Color.FromArgb(100, 148, 163, 184);
Both width properties accept positive values independently. Set
MinExpandedWidth <= MaxExpandedWidth so the drag range is meaningful.
Snap dragged widths to a grid
private void sidebar_UserResizing(object sender, SiticoneSidebarResizeEventArgs e)
{
const int step = 20;
int snapped = ((e.ProposedWidth + (step / 2)) / step) * step;
e.ProposedWidth = Math.Max(
e.MinimumWidth,
Math.Min(e.MaximumWidth, snapped));
}
Cancel resize at the start
private void sidebar_UserResizeStarted(object sender, SiticoneSidebarResizeEventArgs e)
{
if (!currentUserCanCustomizeLayout)
{
e.Cancel = true;
statusLabel.Text = "Your layout is managed by an administrator.";
}
}
Cancel an active drag programmatically
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape && sidebar.IsUserResizing)
{
sidebar.CancelUserResize();
e.Handled = true;
}
}
Inspect the grip bounds
Rectangle grip = sidebar.GetResizeGripBounds();
bool mouseIsOverGrip = grip.Contains(sidebar.PointToClient(Control.MousePosition));
Remember state between application runs
Persistence can remember the expanded/collapsed state, the expanded width, and optionally the selected item index. Built-in file mode stores a small state value below the current user's application-data location. Custom mode lets the application store the same state string in its own settings, registry, database, or configuration service through the persistence events.
Use the built-in per-user file
private void ConfigurePersistence()
{
sidebar.PersistenceKey = "MainNavigation";
sidebar.PersistenceMode = SiticoneSidebarPersistenceMode.ApplicationDataFile;
sidebar.PersistExpandedState = true;
sidebar.PersistWidth = true;
sidebar.PersistSelectedIndex = true;
sidebar.AutoPersist = true;
sidebar.EnablePersistence = true;
}
When EnablePersistence is already true as the runtime control is created, it calls
LoadState() automatically. If you enable persistence later, call LoadState()
yourself. Add navigation items before loading when PersistSelectedIndex is enabled so the saved
index can resolve against the final item order.
Save, load, or clear manually
private void saveLayoutButton_Click(object sender, EventArgs e)
{
bool saved = sidebar.SaveState();
statusLabel.Text = saved ? "Layout saved" : "Layout could not be saved";
}
private void restoreLayoutButton_Click(object sender, EventArgs e)
{
bool applied = sidebar.LoadState();
statusLabel.Text = applied ? "Saved layout restored" : "No saved layout was applied";
}
private void resetLayoutButton_Click(object sender, EventArgs e)
{
bool deleted = sidebar.ClearPersistedState();
statusLabel.Text = deleted ? "Saved layout removed" : "No saved file was removed";
}
SaveState() returns true when storage succeeded. LoadState() returns true only when
a non-empty state was applied; “no saved state yet” therefore returns false without necessarily being an
error. ClearPersistedState() returns true only when file mode deleted an existing file; custom
mode returns false because the application owns that storage.
Show the resolved key and file path
persistenceKeyLabel.Text = sidebar.EffectivePersistenceKey;
if (sidebar.PersistenceMode == SiticoneSidebarPersistenceMode.ApplicationDataFile)
{
persistencePathLabel.Text = sidebar.PersistenceFilePath;
}
A non-empty PersistenceKey is used first. Otherwise the control's standard WinForms
Name is used. If both are empty, the fallback key is SiticoneLeftSidebar.
Give multiple sidebars distinct keys.
Store state yourself in custom mode
The following complete Windows example stores the state in the current-user registry. The important contract
is simple: save e.State during StateSaving, and assign the previously saved string to
e.State during StateLoading. Store the value unchanged unless your application has a
deliberate transformation layer.
using Microsoft.Win32;
private const string SidebarRegistryPath = @"Software\Contoso\DesktopApp\Sidebars";
private void ConfigureCustomPersistence()
{
sidebar.PersistenceKey = "MainNavigation";
sidebar.PersistenceMode = SiticoneSidebarPersistenceMode.Custom;
sidebar.PersistExpandedState = true;
sidebar.PersistWidth = true;
sidebar.PersistSelectedIndex = true;
sidebar.StateSaving += Sidebar_StateSaving;
sidebar.StateLoading += Sidebar_StateLoading;
sidebar.EnablePersistence = true;
}
private void Sidebar_StateSaving(object sender, SiticoneSidebarPersistenceEventArgs e)
{
try
{
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(SidebarRegistryPath))
{
if (key == null)
{
e.Cancel = true;
return;
}
key.SetValue(e.Key, e.State, RegistryValueKind.String);
}
}
catch (Exception)
{
e.Cancel = true;
}
}
private void Sidebar_StateLoading(object sender, SiticoneSidebarPersistenceEventArgs e)
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(SidebarRegistryPath))
{
object value = key == null ? null : key.GetValue(e.Key);
e.State = Convert.ToString(value) ?? string.Empty;
}
}
Report save/load failures without exceptions escaping into the UI
private void sidebar_StateSaved(
object sender,
SiticoneSidebarPersistenceCompletedEventArgs e)
{
if (!e.Succeeded)
{
statusLabel.Text = e.Error == null
? "Sidebar state was not saved."
: "Sidebar state was not saved: " + e.Error.Message;
}
}
private void sidebar_StateLoaded(
object sender,
SiticoneSidebarPersistenceCompletedEventArgs e)
{
if (!e.Succeeded && e.Error != null)
{
statusLabel.Text = "Sidebar state was not loaded: " + e.Error.Message;
}
}
Keyboard navigation and shortcuts
Keyboard support has two parts. The toggle shortcut is application-wide while the sidebar is active in the application; item navigation works when focus is inside the sidebar. Visible and enabled items participate, navigation wraps at the ends, and Enter/Space can activate the focused item.
sidebar.EnableKeyboardNavigation = true;
sidebar.ToggleShortcut = Keys.Control | Keys.B;
sidebar.EnableArrowNavigation = true;
sidebar.ActivateItemOnEnter = true;
// Optional: Escape closes an expanded sidebar.
sidebar.AutoCloseOnEscape = true;
| Key | Requirement | Result |
|---|---|---|
ToggleShortcut (default Ctrl+B) |
EnableKeyboardNavigation = true and shortcut is not Keys.None |
Toggles the sidebar from anywhere in the application unless ShortcutActivated cancels. |
| Up / Down | Sidebar contains focus and EnableArrowNavigation = true |
Moves focus to the previous/next visible enabled item, wrapping at either end. |
| Home / End | Same as arrow keys | Moves focus to the first/last visible enabled item. |
| Enter / Space | Sidebar contains focus and ActivateItemOnEnter = true |
Calls the focused item's activation path; non-selectable items still run their action. |
| Escape | AutoCloseOnEscape = true |
Collapses an expanded, non-animating sidebar. |
The configured toggle shortcut is evaluated before AutoCloseOnEscape. Keep the default Ctrl+B
or choose another combination when Escape must never expand a collapsed sidebar.
Disable the global shortcut but keep local arrows
sidebar.EnableKeyboardNavigation = true;
sidebar.ToggleShortcut = Keys.None;
sidebar.EnableArrowNavigation = true;
sidebar.ActivateItemOnEnter = true;
Cancel the shortcut while the user is typing
private void sidebar_ShortcutActivated(object sender, SiticoneSidebarShortcutEventArgs e)
{
TextBoxBase editor = ActiveControl as TextBoxBase;
if (editor != null)
{
e.Cancel = true;
}
}
Prevent focus from entering a protected item
private void sidebar_KeyNavigating(object sender, SiticoneSidebarNavigationEventArgs e)
{
if (ReferenceEquals(e.ToItem, administrationItem) && !currentUserIsAdministrator)
{
e.Cancel = true;
statusLabel.Text = "Administration access is required.";
}
}
Move focus from code
bool moved = sidebar.MoveFocusTo(
SiticoneSidebarNavigationDirection.First,
Keys.Home);
if (!moved)
{
statusLabel.Text = "There is no visible, enabled navigation item to focus.";
}
DPI scaling and shadow performance
DPI scaling is enabled by default. The sidebar rescales its expanded and collapsed widths, user-resize clamps,
explicit rail-switch width, and shadow depth as its control scale changes. CurrentDpi reports the
DPI used for the current metrics.
private void ConfigureDpiSupport()
{
sidebar.EnableDpiScaling = true;
sidebar.DpiScaleChanged += Sidebar_DpiScaleChanged;
}
private void Sidebar_DpiScaleChanged(object sender, SiticoneSidebarDpiEventArgs e)
{
dpiLabel.Text = string.Format(
"{0:0} DPI to {1:0} DPI (x{2:0.00}); width {3}px",
e.OldDpi,
e.NewDpi,
e.ScaleFactor,
e.ExpandedWidth);
}
Rescale manually
// Example: convert metrics from 96 DPI to 120 DPI.
float factor = 120f / 96f;
sidebar.RescaleForDpi(factor);
Pass the ratio between the new and old scale, not an absolute DPI value. Calling it twice scales the
already-scaled metrics twice. Normal WinForms layout scaling calls the control's automatic path when
EnableDpiScaling is true, so most applications should not call it manually.
Use and diagnose the shadow cache
CacheShadow is true by default. It is especially useful during width animation because the shadow
can be reused until a setting or relevant size changes. The diagnostic event reports the cache size, rendered
layer count, and rebuild time.
private void ConfigureShadowDiagnostics()
{
sidebar.CacheShadow = true;
sidebar.ShadowCacheRebuilt += delegate(object sender, SiticoneSidebarShadowCacheEventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format(
"Sidebar shadow: {0}x{1}, {2} layers, {3:0.00} ms",
e.CacheSize.Width,
e.CacheSize.Height,
e.LayerCount,
e.ElapsedMilliseconds));
};
}
private void ForceShadowRebuildOnNextPaint()
{
sidebar.InvalidateShadowCache();
sidebar.Invalidate();
}
Event lifecycle and practical event handling
The sidebar exposes cancellable “before” events, detailed progress events, and completed events. Subscribe only to the events your application needs. The full event table later in this page lists every public event and its exact event-argument type.
Expand/collapse event order
For an accepted animated transition, events occur in this order:
- BeforeExpand / BeforeCollapse
- AnimationStarted
- AnimationProgressChanged (0..many)
- AfterExpand / AfterCollapse
- SidebarStateChanged
- AnimationCompleted
A non-animated transition raises the before event, its matching after event, and
SidebarStateChanged; it does not raise animation events. If a before event cancels, no transition
or completion events follow. A request that already matches the stable state and target width is ignored.
Cancel collapse when the current page is unsafe to leave
private void sidebar_BeforeCollapse(object sender, SiticoneSidebarCancelEventArgs e)
{
if (_navigationContainsUnsavedWork)
{
e.Cancel = true;
statusLabel.Text = "Save or discard your changes before closing navigation.";
}
}
React differently to each trigger
private void sidebar_AfterCollapse(object sender, SiticoneSidebarEventArgs e)
{
switch (e.Reason)
{
case SiticoneSidebarTriggerReason.OutsideClick:
statusLabel.Text = "Navigation closed after an outside click.";
break;
case SiticoneSidebarTriggerReason.EscapeKey:
statusLabel.Text = "Navigation closed with Escape.";
break;
case SiticoneSidebarTriggerReason.Scrim:
statusLabel.Text = "Navigation closed from the overlay.";
break;
default:
statusLabel.Text = "Navigation closed.";
break;
}
}
Track animation progress
private void sidebar_AnimationProgressChanged(
object sender,
SiticoneSidebarAnimationProgressEventArgs e)
{
animationProgressBar.Value = Math.Max(
animationProgressBar.Minimum,
Math.Min(animationProgressBar.Maximum, (int)Math.Round(e.Progress * 100f)));
widthLabel.Text = e.CurrentWidth + " px";
}
Log a complete high-level interaction trail
private void AttachSidebarDiagnostics()
{
sidebar.AfterExpand += delegate(object sender, SiticoneSidebarEventArgs e)
{
Log("Expanded to " + e.Width + " px; reason: " + e.Reason);
};
sidebar.AfterCollapse += delegate(object sender, SiticoneSidebarEventArgs e)
{
Log("Collapsed to " + e.Width + " px; reason: " + e.Reason);
};
sidebar.ItemSelectionChanged += delegate(object sender, SiticoneSidebarSelectionChangedEventArgs e)
{
Log("Selected item " + e.SelectedIndex + ": " + e.SelectedText);
};
sidebar.UserResizeCompleted += delegate(object sender, SiticoneSidebarResizeCompletedEventArgs e)
{
Log("Resize completed at " + e.FinalWidth + " px; cancelled: " + e.Cancelled);
};
sidebar.SideChanged += delegate(object sender, SiticoneSidebarSideChangedEventArgs e)
{
Log("Sidebar moved from " + e.OldSide + " to " + e.NewSide);
};
}
private void Log(string message)
{
System.Diagnostics.Debug.WriteLine(message);
}
Complete SiticoneLeftSidebar property reference
Defaults and accepted ranges below come directly from the supplied control source. When a numeric setter has a range, values outside that range are clamped unless the row says otherwise. “Read only” means the property is runtime information rather than a designer setting.
Appearance, shadow, and border
| Property | Type | Default / range | Purpose and example |
|---|---|---|---|
| EnableGradient | bool | false | Uses the two gradient colors instead of the normal BackColor.sidebar.EnableGradient = true; |
| GradientStartColor | Color | Color.White | First gradient color.sidebar.GradientStartColor = Color.Navy; |
| GradientEndColor | Color | Color.Gainsboro | Second gradient color.sidebar.GradientEndColor = Color.SteelBlue; |
| GradientAngle | float | 90f; no clamp | Gradient angle in degrees.sidebar.GradientAngle = 135f; |
| CornerRadius | int | 0; 0..60 | Sidebar-body corner radius; zero gives square corners.sidebar.CornerRadius = 12; |
| RoundRightCornersOnly | bool | true | Rounds only the inner/shadow edge: right for a left sidebar, left for a right sidebar.sidebar.RoundRightCornersOnly = true; |
| EnableDropShadow | bool | true | Turns the edge shadow on or off.sidebar.EnableDropShadow = false; |
| ShadowDepth | int | 15; 0..30 | Shadow depth and reserved edge area.sidebar.ShadowDepth = 18; |
| ShadowColor | Color | ARGB(60,100,100,111) | Base color; its alpha controls intensity.sidebar.ShadowColor = Color.FromArgb(50, 0, 0, 0); |
| ShadowBlur | int | 40; 1..120 | Softness radius comparable to a CSS shadow blur.sidebar.ShadowBlur = 48; |
| ShadowSpread | int | 15; 0..80 | Shadow spread radius.sidebar.ShadowSpread = 12; |
| ShadowVerticalOffset | int | 5; -40..40 | Moves the shadow vertically; negative values move it upward.sidebar.ShadowVerticalOffset = 3; |
| ReserveShadowSpace | bool | true | Uses sidebar padding to keep docked children away from the shadow edge.sidebar.ReserveShadowSpace = true; |
| RightBorderThickness | int | 1; 1..10 | Thickness of the inner edge border; use RightBorderVisible to show none.sidebar.RightBorderThickness = 2; |
| RightBorderColor | Color | Color.Silver | Inner edge border color. Transparent is accepted.sidebar.RightBorderColor = Color.SlateGray; |
| RightBorderVisible | bool | true | Shows or hides the edge border without losing its settings.sidebar.RightBorderVisible = false; |
| EdgeBorderThickness | int | Alias; 1..10 | Non-directional alias of RightBorderThickness; hidden from designer serialization.sidebar.EdgeBorderThickness = 1; |
| EdgeBorderColor | Color | Alias of Silver | Non-directional alias of RightBorderColor; hidden from designer serialization.sidebar.EdgeBorderColor = Color.Gray; |
Layout, state, behavior, animation, and docking
| Property | Type | Default / range | Purpose and example |
|---|---|---|---|
| IsExpanded | bool | true | Gets or requests the open state. Assignment uses normal animation settings.sidebar.IsExpanded = false; |
| ExpandedWidth | int | 240; minimum 1 | Target width when open; updates the current width immediately when stably expanded.sidebar.ExpandedWidth = 280; |
| CollapsedWidth | int | 56; minimum 0 | Target width when closed; zero is allowed.sidebar.CollapsedWidth = 60; |
| AutoCaptureExpandedWidth | bool | true | Captures the current wider width into ExpandedWidth when collapse begins.sidebar.AutoCaptureExpandedWidth = false; |
| CollapseMode | SiticoneSidebarCollapseMode | Width | Keeps the collapsed-width control visible or hides it after collapse.sidebar.CollapseMode = SiticoneSidebarCollapseMode.Hide; |
| HideChildrenWhenCollapsed | bool | false | Temporarily hides children at the completed collapsed state and restores their prior visibility on expand.sidebar.HideChildrenWhenCollapsed = true; |
| BringToFrontOnExpand | bool | false | Moves the sidebar to the front of sibling z-order when opening.sidebar.BringToFrontOnExpand = true; |
| State | SiticoneSidebarState | Read only | Reports Collapsed, Expanded, or Animating.if (sidebar.State == SiticoneSidebarState.Animating) return; |
| IsAnimating | bool | Read only; false | True while the expand/collapse animation is running.animationLabel.Visible = sidebar.IsAnimating; |
| AutoCloseOnOutsideClick | bool | false | Closes an expanded sidebar after an eligible managed-control click outside it.sidebar.AutoCloseOnOutsideClick = true; |
| AutoCloseOnEscape | bool | false | Closes an expanded sidebar when Escape is pressed.sidebar.AutoCloseOnEscape = true; |
| AutoCloseOnTitleBarClick | bool | false | Includes non-client/title-bar clicks in outside-click closing.sidebar.AutoCloseOnTitleBarClick = true; |
| ExpandOnHover | bool | false | Opens a collapsed visible sidebar after the pointer remains inside it.sidebar.ExpandOnHover = true; |
| CollapseOnMouseLeave | bool | true | Closes an expanded sidebar after the pointer leaves while hover tracking is active; used with ExpandOnHover.sidebar.CollapseOnMouseLeave = false; |
| HoverExpandDelay | int | 250; 0..5000 ms | Delay before hover expansion.sidebar.HoverExpandDelay = 400; |
| ToggleControl | Control | null | Control whose Click automatically toggles the sidebar; automatically excluded from outside-close.sidebar.ToggleControl = menuButton; |
| OutsideClickExceptions | IList<Control> | Read only; empty | Read-only view of controls registered through the exception methods.int count = sidebar.OutsideClickExceptions.Count; |
| EnableAnimation | bool | true | Enables normal expand/collapse animation.sidebar.EnableAnimation = false; |
| AnimationDuration | int | 220; 0..3000 ms | Configured transition duration. Zero prevents animation.sidebar.AnimationDuration = 180; |
| AnimationEasing | SiticoneSidebarEasing | EaseInOut | Linear, accelerating, decelerating, or combined easing.sidebar.AnimationEasing = SiticoneSidebarEasing.EaseOut; |
| SidebarSide | SiticoneSidebarSide | Left | Controls edge mirroring and, by default, docking.sidebar.SidebarSide = SiticoneSidebarSide.Right; |
| AutoDock | bool | true | Applies matching left/right Dock when SidebarSide changes.sidebar.AutoDock = false; |
Icon rail and tooltips
| Property | Type | Default / range | Purpose and example |
|---|---|---|---|
| EnableIconRailMode | bool | false | Switches rail-aware descendants to compact presentation at the threshold.sidebar.EnableIconRailMode = true; |
| RailSwitchWidth | int | 0; minimum 0 | Explicit rail threshold; zero derives it from CollapsedWidth.sidebar.RailSwitchWidth = 84; |
| EffectiveRailSwitchWidth | int | Read only; 80 initially | Resolved threshold: explicit value, otherwise CollapsedWidth + 24.int threshold = sidebar.EffectiveRailSwitchWidth; |
| IsRailCollapsed | bool | Read only; false | True when rail mode is enabled and the current width is at/below the threshold.railLabel.Visible = sidebar.IsRailCollapsed; |
| Items | IList<SiticoneSidebarItem> | Read only; empty | Snapshot ordered by each registered item's visual top/left position.foreach (SiticoneSidebarItem item in sidebar.Items) { item.Height = 48; } |
| SelectedItem | SiticoneSidebarItem | null | Gets or requests the selected item; assigning null clears selection.sidebar.SelectedItem = dashboardItem; |
| SelectedIndex | int | -1 | Selected visual-order index; an invalid assigned value clears selection.sidebar.SelectedIndex = 0; |
| EnableCollapsedToolTips | bool | true | Shows item captions/custom text as tooltips in collapsed rail mode.sidebar.EnableCollapsedToolTips = true; |
| ShowToolTipsWhenExpanded | bool | false | Also attaches item tooltips in the full layout.sidebar.ShowToolTipsWhenExpanded = true; |
| ToolTipInitialDelay | int | 400; 0..30000 ms | Delay before the first tooltip appears.sidebar.ToolTipInitialDelay = 300; |
| ToolTipAutoPopDelay | int | 5000; 100..60000 ms | How long a tooltip stays visible.sidebar.ToolTipAutoPopDelay = 7000; |
| ToolTipReshowDelay | int | 100; 0..30000 ms | Delay before a following item's tooltip appears.sidebar.ToolTipReshowDelay = 80; |
Scrim and user resize
| Property | Type | Default / range | Purpose and example |
|---|---|---|---|
| EnableScrim | bool | false | Dims the form area next to an expanded sidebar.sidebar.EnableScrim = true; |
| ScrimColor | Color | Color.Black | Overlay color.sidebar.ScrimColor = Color.Navy; |
| ScrimOpacity | int | 35; 0..100% | Target overlay opacity as a whole-number percentage.sidebar.ScrimOpacity = 40; |
| ScrimClosesSidebar | bool | true | Allows a non-cancelled scrim click to collapse the sidebar.sidebar.ScrimClosesSidebar = false; |
| IsScrimVisible | bool | Read only; false | Reports whether the overlay is currently shown.overlayLabel.Visible = sidebar.IsScrimVisible; |
| EnableUserResize | bool | false | Lets users drag the inner edge while stably expanded.sidebar.EnableUserResize = true; |
| ResizeGripSize | int | 6; 2..24 | Width of the draggable edge zone.sidebar.ResizeGripSize = 8; |
| MinExpandedWidth | int | 120; minimum 1 | Smallest normal proposed drag width.sidebar.MinExpandedWidth = 180; |
| MaxExpandedWidth | int | 480; minimum 1 | Largest normal proposed drag width.sidebar.MaxExpandedWidth = 420; |
| ShowResizeCursor | bool | true | Uses the horizontal resize cursor over the grip.sidebar.ShowResizeCursor = true; |
| ResizeGripColor | Color | Color.Empty | Optional small visual grip marker; empty means no marker.sidebar.ResizeGripColor = Color.Gray; |
| IsUserResizing | bool | Read only; false | Reports whether a grip drag is currently active.if (sidebar.IsUserResizing) sidebar.CancelUserResize(); |
Persistence
| Property | Type | Default | Purpose and example |
|---|---|---|---|
| EnablePersistence | bool | false | Enables initial loading and eligible automatic saves.sidebar.EnablePersistence = true; |
| PersistenceKey | string | String.Empty | Explicit storage key; null assignments become empty.sidebar.PersistenceKey = "MainNavigation"; |
| EffectivePersistenceKey | string | Read only; Name/fallback | Resolved explicit key, control name, or final type-name fallback.string key = sidebar.EffectivePersistenceKey; |
| PersistenceMode | SiticoneSidebarPersistenceMode | ApplicationDataFile | Selects built-in per-user file or event-driven custom storage.sidebar.PersistenceMode = SiticoneSidebarPersistenceMode.Custom; |
| PersistExpandedState | bool | true | Includes open/closed state.sidebar.PersistExpandedState = true; |
| PersistWidth | bool | true | Includes ExpandedWidth.sidebar.PersistWidth = true; |
| PersistSelectedIndex | bool | false | Includes the selected item's ordered index; ensure items exist before loading.sidebar.PersistSelectedIndex = true; |
| AutoPersist | bool | true | Saves after accepted state, completed resize, or selection changes once initial restoration is complete.sidebar.AutoPersist = false; |
| PersistenceFilePath | string | Read only | Resolved file path for ApplicationDataFile mode.pathLabel.Text = sidebar.PersistenceFilePath; |
DPI, performance, keyboard, and regions
| Property | Type | Default / range | Purpose and example |
|---|---|---|---|
| EnableDpiScaling | bool | true | Rescales width-related metrics with control scaling.sidebar.EnableDpiScaling = true; |
| CurrentDpi | float | Read only; starts at 96 | DPI for which current metrics were calculated.dpiLabel.Text = sidebar.CurrentDpi.ToString("0"); |
| CacheShadow | bool | true | Reuses a rendered shadow bitmap instead of recomposing on every paint.sidebar.CacheShadow = true; |
| EnableKeyboardNavigation | bool | false | Activates shortcut and item keyboard behavior.sidebar.EnableKeyboardNavigation = true; |
| ToggleShortcut | Keys | Control | B | Application-wide toggle combination; Keys.None disables it.sidebar.ToggleShortcut = Keys.Control | Keys.M; |
| EnableArrowNavigation | bool | true | Enables Up/Down/Home/End item focus movement.sidebar.EnableArrowNavigation = false; |
| ActivateItemOnEnter | bool | true | Lets Enter/Space activate the focused item.sidebar.ActivateItemOnEnter = true; |
| EnableRegions | bool | false | Creates fixed header/footer and fill content regions.sidebar.EnableRegions = true; |
| HeaderPanel | Panel | Read only; null if disabled | Fixed top region.sidebar.HeaderPanel.Controls.Add(logo); |
| ContentPanel | Panel | Read only; null if disabled | Fill region, optionally scrollable.sidebar.ContentPanel.Controls.Add(navigationPanel); |
| FooterPanel | Panel | Read only; null if disabled | Fixed bottom region.sidebar.FooterPanel.Controls.Add(accountButton); |
| ItemHost | Control | Read only | Content panel when regions are enabled; otherwise the sidebar itself.sidebar.ItemHost.Controls.Add(sectionLabel); |
| HeaderHeight | int | 64; minimum 0 | Fixed header height.sidebar.HeaderHeight = 72; |
| FooterHeight | int | 56; minimum 0 | Fixed footer height.sidebar.FooterHeight = 64; |
| HeaderVisible | bool | true | Shows/hides the header panel when it exists.sidebar.HeaderVisible = false; |
| FooterVisible | bool | true | Shows/hides the footer panel when it exists.sidebar.FooterVisible = false; |
| ContentAutoScroll | bool | true | Controls content-panel scrolling when items exceed available height.sidebar.ContentAutoScroll = true; |
| MoveExistingChildrenToContent | bool | true | Moves direct children into content as regions are enabled/used at runtime.sidebar.MoveExistingChildrenToContent = false; |
Complete SiticoneLeftSidebar method reference
| Method | Returns | What it does | Example |
|---|---|---|---|
| Expand() | void | Opens using EnableAnimation. |
sidebar.Expand(); |
| Expand(bool animate) | void | Opens; false forces an immediate transition. True still respects EnableAnimation and duration. |
sidebar.Expand(false); |
| Collapse() | void | Closes using EnableAnimation. |
sidebar.Collapse(); |
| Collapse(bool animate) | void | Closes; false forces an immediate transition. | sidebar.Collapse(false); |
| Toggle() | void | Requests the opposite stable state using normal animation settings. | sidebar.Toggle(); |
| Toggle(bool animate) | void | Toggles with optional forced immediate movement. | sidebar.Toggle(false); |
| AddOutsideClickException(Control) | void | Excludes a control and descendants from outside-click close. Null/duplicates are ignored. | sidebar.AddOutsideClickException(accountPopup); |
| RemoveOutsideClickException(Control) | void | Stops excluding a previously registered control. Null/missing values are ignored. | sidebar.RemoveOutsideClickException(accountPopup); |
| ClearOutsideClickExceptions() | void | Clears all manually registered outside-click exceptions. | sidebar.ClearOutsideClickExceptions(); |
| ApplyTheme(string, Color, Color) | void | Sets sidebar background/foreground and raises ThemeApplied. |
sidebar.ApplyTheme("Dark", darkBack, lightFore); |
| ResetShadowColor() | void | Restores ARGB(60,100,100,111). | sidebar.ResetShadowColor(); |
| ResetRightBorderColor() | void | Restores Color.Silver. |
sidebar.ResetRightBorderColor(); |
| ResetGradientStartColor() | void | Restores Color.White. |
sidebar.ResetGradientStartColor(); |
| ResetGradientEndColor() | void | Restores Color.Gainsboro. |
sidebar.ResetGradientEndColor(); |
| ResetScrimColor() | void | Restores Color.Black. |
sidebar.ResetScrimColor(); |
| ResetResizeGripColor() | void | Restores Color.Empty (no marker). |
sidebar.ResetResizeGripColor(); |
| ShouldSerializeShadowColor() | bool | Designer helper: true when ShadowColor differs from its default. |
bool custom = sidebar.ShouldSerializeShadowColor(); |
| ShouldSerializeRightBorderColor() | bool | Designer helper for RightBorderColor. |
bool custom = sidebar.ShouldSerializeRightBorderColor(); |
| ShouldSerializeGradientStartColor() | bool | Designer helper for GradientStartColor. |
bool custom = sidebar.ShouldSerializeGradientStartColor(); |
| ShouldSerializeGradientEndColor() | bool | Designer helper for GradientEndColor. |
bool custom = sidebar.ShouldSerializeGradientEndColor(); |
| ShouldSerializeScrimColor() | bool | Designer helper for ScrimColor. |
bool custom = sidebar.ShouldSerializeScrimColor(); |
| ShouldSerializeResizeGripColor() | bool | Designer helper for ResizeGripColor. |
bool custom = sidebar.ShouldSerializeResizeGripColor(); |
| AddItem(string) | SiticoneSidebarItem | Creates and adds a caption-only item. | SiticoneSidebarItem item = sidebar.AddItem("Home"); |
| AddItem(string, Image) | SiticoneSidebarItem | Creates and adds an item with a bitmap icon. | sidebar.AddItem("Home", Resources.Home); |
| AddItem(string, Image, EventHandler) | SiticoneSidebarItem | Creates and adds an item, optionally wiring its inherited Click event. |
sidebar.AddItem("Home", icon, delegate { ShowHome(); }); |
| AddGlyphItem(string, string, Font, EventHandler) | SiticoneSidebarItem | Creates and adds a font-glyph item; handler and font may be null. | sidebar.AddGlyphItem("Settings", "\uE713", glyphFont, null); |
| AddItem(SiticoneSidebarItem) | void | Adds an existing non-null item to ItemHost, docks it top, and registers it. |
sidebar.AddItem(customItem); |
| RemoveItem(SiticoneSidebarItem) | void | Unregisters, removes, and disposes the item. Null is ignored. | sidebar.RemoveItem(retiredItem); |
| ClearItems() | void | Removes and disposes every registered item. | sidebar.ClearItems(); |
| RegisterItem(SiticoneSidebarItem) | void | Starts sidebar tracking/events/rail/tooltips for an item; items under the sidebar normally register automatically. | sidebar.RegisterItem(existingChildItem); |
| UnregisterItem(SiticoneSidebarItem) | void | Stops tracking without removing or disposing the control. | sidebar.UnregisterItem(existingChildItem); |
| IndexOfItem(SiticoneSidebarItem) | int | Returns zero-based visual-order index or -1. | int index = sidebar.IndexOfItem(item); |
| SelectItem(SiticoneSidebarItem) | void | Selects using reason Code; null clears. An unregistered non-null item is registered first. |
sidebar.SelectItem(homeItem); |
| SelectItem(SiticoneSidebarItem, SiticoneSidebarTriggerReason) | void | Selects with an explicit reason carried by selection events. | sidebar.SelectItem(homeItem, SiticoneSidebarTriggerReason.Code); |
| SelectIndex(int) | void | Selects the visual-order index; invalid values clear selection. | sidebar.SelectIndex(0); |
| ClearSelection() | void | Requests no selected item through cancellable selection events. | sidebar.ClearSelection(); |
| RefreshItems() | void | Reapplies rail state and invalidates registered item visuals. | sidebar.RefreshItems(); |
| RefreshItemToolTip(SiticoneSidebarItem) | void | Re-evaluates one item's final tooltip. Null/disposed/design-time items are ignored. | sidebar.RefreshItemToolTip(homeItem); |
| CalculateScrimBounds() | Rectangle | Returns screen coordinates for the form area next to the sidebar, or empty when unavailable. | Rectangle area = sidebar.CalculateScrimBounds(); |
| GetResizeGripBounds() | Rectangle | Returns the draggable grip zone in sidebar client coordinates. | Rectangle grip = sidebar.GetResizeGripBounds(); |
| CancelUserResize() | void | Cancels an active drag and restores its starting width; does nothing when no drag is active. | sidebar.CancelUserResize(); |
| SaveState() | bool | Raises saving events and stores current enabled state fields; returns storage success. | bool saved = sidebar.SaveState(); |
| LoadState() | bool | Raises loading events and applies non-empty state; returns whether state was applied. | bool applied = sidebar.LoadState(); |
| ClearPersistedState() | bool | Deletes an existing built-in state file; false for custom mode, no file, or failure. | bool deleted = sidebar.ClearPersistedState(); |
| RescaleForDpi(float) | void | Multiplies relevant metrics by a positive factor; non-positive factors are ignored. | sidebar.RescaleForDpi(1.25f); |
| MoveFocusTo(SiticoneSidebarNavigationDirection, Keys) | bool | Moves among visible enabled items; returns false when no target or when cancelled. | bool moved = sidebar.MoveFocusTo(SiticoneSidebarNavigationDirection.Next, Keys.Down); |
| InvalidateShadowCache() | void | Discards the cached shadow so the next relevant paint can rebuild it. | sidebar.InvalidateShadowCache(); sidebar.Invalidate(); |
The public ShouldSerialize... helpers let the WinForms designer decide whether custom color
values must be written to InitializeComponent. Application code rarely needs to call them, but
they are listed because they are part of the public API.
Complete SiticoneLeftSidebar event reference
| Event | Event arguments | Cancellable? | When to use it |
|---|---|---|---|
| SidebarStateChanged | EventArgs | No | After either transition finishes. Read State/IsExpanded.sidebar.SidebarStateChanged += delegate { UpdateSidebarStatus(); }; |
| BeforeExpand | SiticoneSidebarCancelEventArgs | Yes | Validate or prevent opening before width changes.sidebar.BeforeExpand += delegate(object s, SiticoneSidebarCancelEventArgs e) { e.Cancel = !CanOpen(); }; |
| AfterExpand | SiticoneSidebarEventArgs | No | Use final width and trigger reason after opening.sidebar.AfterExpand += delegate(object s, SiticoneSidebarEventArgs e) { Log(e.Width.ToString()); }; |
| BeforeCollapse | SiticoneSidebarCancelEventArgs | Yes | Protect unfinished work before closing.sidebar.BeforeCollapse += Sidebar_BeforeCollapse; |
| AfterCollapse | SiticoneSidebarEventArgs | No | React after close and inspect reason/final width.sidebar.AfterCollapse += Sidebar_AfterCollapse; |
| AnimationStarted | SiticoneSidebarAnimationEventArgs | No | Prepare companion UI using from/to widths and duration.sidebar.AnimationStarted += Sidebar_AnimationStarted; |
| AnimationProgressChanged | SiticoneSidebarAnimationProgressEventArgs | No | Observe each animated frame's linear/eased progress and current width.sidebar.AnimationProgressChanged += Sidebar_AnimationProgressChanged; |
| AnimationCompleted | SiticoneSidebarAnimationEventArgs | No | Finalize companion animation; raised only for animated transitions.sidebar.AnimationCompleted += Sidebar_AnimationCompleted; |
| OutsideClicked | SiticoneSidebarOutsideClickEventArgs | Yes | Inspect/cancel an eligible outside-click auto-close.sidebar.OutsideClicked += Sidebar_OutsideClicked; |
| ToggleRequested | EventArgs | No | Observe a click on the assigned ToggleControl; it occurs before the toggle request.sidebar.ToggleRequested += delegate { Log("Toggle button"); }; |
| ThemeApplied | SiticoneSidebarThemeEventArgs | No | React after public ApplyTheme sets its color pair.sidebar.ThemeApplied += Sidebar_ThemeApplied; |
| ItemAdded | SiticoneSidebarItemEventArgs | No | Observe registration and resulting visual-order index.sidebar.ItemAdded += Sidebar_ItemAdded; |
| ItemRemoved | SiticoneSidebarItemEventArgs | No | Observe unregistration; index is captured before removal.sidebar.ItemRemoved += Sidebar_ItemRemoved; |
| ItemClicked | SiticoneSidebarItemEventArgs | No | Central notification for registered item mouse/keyboard clicks. Selection timing differs for direct clicks versus PerformActivate(); use selection events when order matters.sidebar.ItemClicked += Sidebar_ItemClicked; |
| ItemMouseEnter | SiticoneSidebarItemMouseEventArgs | No | Observe pointer entry with item-relative location and rail state.sidebar.ItemMouseEnter += Sidebar_ItemMouseEnter; |
| ItemMouseLeave | SiticoneSidebarItemMouseEventArgs | No | Observe pointer departure with item-relative location and rail state.sidebar.ItemMouseLeave += Sidebar_ItemMouseLeave; |
| ItemSelectionChanging | SiticoneSidebarSelectionChangingEventArgs | Yes | Validate old/new items before selection changes or clears.sidebar.ItemSelectionChanging += Sidebar_ItemSelectionChanging; |
| ItemSelectionChanged | SiticoneSidebarSelectionChangedEventArgs | No | Navigate after selection succeeds; includes selected text/tag helpers.sidebar.ItemSelectionChanged += Sidebar_ItemSelectionChanged; |
| RailModeChanged | SiticoneSidebarRailEventArgs | No | Observe full/rail layout notifications and usable content width.sidebar.RailModeChanged += Sidebar_RailModeChanged; |
| ItemToolTipShowing | SiticoneSidebarToolTipEventArgs | Yes | Change Text or cancel before a tooltip is assigned.sidebar.ItemToolTipShowing += Sidebar_ItemToolTipShowing; |
| ScrimShown | SiticoneSidebarScrimVisibilityEventArgs | No | Observe overlay visibility, bounds, and target/current opacity.sidebar.ScrimShown += Sidebar_ScrimShown; |
| ScrimHidden | SiticoneSidebarScrimVisibilityEventArgs | No | Observe overlay removal and its last bounds/opacity.sidebar.ScrimHidden += Sidebar_ScrimHidden; |
| ScrimClicked | SiticoneSidebarScrimEventArgs | Yes | Inspect/cancel overlay-click closing; ScrimClosesSidebar must also permit close.sidebar.ScrimClicked += Sidebar_ScrimClicked; |
| UserResizeStarted | SiticoneSidebarResizeEventArgs | Yes | Allow or block the drag before capture begins.sidebar.UserResizeStarted += Sidebar_UserResizeStarted; |
| UserResizing | SiticoneSidebarResizeEventArgs | Yes | Change ProposedWidth, or cancel only that update, during a drag.sidebar.UserResizing += Sidebar_UserResizing; |
| UserResizeCompleted | SiticoneSidebarResizeCompletedEventArgs | No | Observe original/final width, delta, and cancellation after drag ends.sidebar.UserResizeCompleted += Sidebar_UserResizeCompleted; |
| StateSaving | SiticoneSidebarPersistenceEventArgs | Yes | Inspect/replace state; in custom mode, store it here. Cancellation stops save and its completed event.sidebar.StateSaving += Sidebar_StateSaving; |
| StateSaved | SiticoneSidebarPersistenceCompletedEventArgs | No | Observe save success/error after a non-cancelled operation.sidebar.StateSaved += Sidebar_StateSaved; |
| StateLoading | SiticoneSidebarPersistenceEventArgs | Yes | Supply custom state or cancel loading. Cancellation stops load and its completed event.sidebar.StateLoading += Sidebar_StateLoading; |
| StateLoaded | SiticoneSidebarPersistenceCompletedEventArgs | No | Observe load/application errors after a non-cancelled operation.sidebar.StateLoaded += Sidebar_StateLoaded; |
| DpiScaleChanged | SiticoneSidebarDpiEventArgs | No | Observe old/new DPI, factor, and selected rescaled metrics.sidebar.DpiScaleChanged += Sidebar_DpiScaleChanged; |
| ShadowCacheRebuilt | SiticoneSidebarShadowCacheEventArgs | No | Profile a cached-shadow rebuild.sidebar.ShadowCacheRebuilt += Sidebar_ShadowCacheRebuilt; |
| ShortcutActivated | SiticoneSidebarShortcutEventArgs | Yes | Inspect shortcut and whether it would expand; cancel contextually.sidebar.ShortcutActivated += Sidebar_ShortcutActivated; |
| KeyNavigating | SiticoneSidebarNavigationEventArgs | Yes | Inspect/cancel a focus move before it occurs.sidebar.KeyNavigating += Sidebar_KeyNavigating; |
| KeyNavigated | SiticoneSidebarNavigationEventArgs | No | Observe the completed focus move.sidebar.KeyNavigated += Sidebar_KeyNavigated; |
| SideChanged | SiticoneSidebarSideChangedEventArgs | No | Observe old/new side and resulting dock style.sidebar.SideChanged += Sidebar_SideChanged; |
| RegionsChanged | SiticoneSidebarRegionEventArgs | No | Observe enabled state and region-panel references.sidebar.RegionsChanged += Sidebar_RegionsChanged; |
Complete SiticoneSidebarItem reference
A new item starts at 44 pixels high, docks to the top, accepts keyboard focus, uses a hand cursor, and has a transparent normal background. It can be dropped in the designer or created in code. The table lists every public property introduced or overridden by the item type.
Item properties
| Property | Type | Default / range | Purpose and example |
|---|---|---|---|
| Text | string | String.Empty | Caption; hidden automatically in rail layout and used as tooltip fallback.item.Text = "Dashboard"; |
| Icon | Image | null | Leading bitmap. When present, it takes visual precedence over Glyph.item.Icon = Properties.Resources.DashboardIcon; |
| IconSize | Size | 20 x 20; each dimension min 1 | Rendered bitmap/glyph box size.item.IconSize = new Size(22, 22); |
| Glyph | string | String.Empty | Text glyph used only when Icon is null; null becomes empty.item.Glyph = "\uE713"; |
| GlyphFont | Font | null | Font containing Glyph; null uses the normal item font.item.GlyphFont = glyphFont; |
| IconColor | Color | Color.Empty | Glyph color; empty follows the current resolved foreground color. Bitmap images keep their image colors.item.IconColor = Color.MediumSeaGreen; |
| HoverBackColor | Color | ARGB(20,0,0,0) | Background while hovered.item.HoverBackColor = Color.FromArgb(24, 0, 0, 0); |
| HoverForeColor | Color | Color.Empty | Foreground while hovered; empty keeps normal ForeColor.item.HoverForeColor = Color.White; |
| PressedBackColor | Color | ARGB(36,0,0,0) | Background while pressed.item.PressedBackColor = Color.FromArgb(40, 0, 0, 0); |
| SelectedBackColor | Color | ARGB(28,0,120,215) | Background of the selected item.item.SelectedBackColor = Color.FromArgb(32, 16, 185, 129); |
| SelectedForeColor | Color | RGB(0,102,204) | Foreground of the selected item.item.SelectedForeColor = Color.SeaGreen; |
| DisabledForeColor | Color | RGB(160,160,160) | Foreground when the inherited Enabled is false.item.DisabledForeColor = Color.DarkGray; |
| CornerRadius | int | 8; 0..40 | Item background radius.item.CornerRadius = 6; |
| IconTextSpacing | int | 12; 0..60 | Horizontal gap between icon and caption.item.IconTextSpacing = 10; |
| ItemPadding | Padding | 14,0,12,0 | Inner content padding; independent of inherited Padding.item.ItemPadding = new Padding(16, 0, 12, 0); |
| ItemMargin | Padding | 6,2,6,2 | Inset from control bounds to painted item body.item.ItemMargin = new Padding(8, 3, 8, 3); |
| ShowSelectionIndicator | bool | true | Shows the leading-edge selected bar.item.ShowSelectionIndicator = false; |
| IndicatorColor | Color | RGB(0,102,204) | Selected bar color.item.IndicatorColor = Color.MediumSeaGreen; |
| IndicatorWidth | int | 4; 0..20 | Selected bar thickness; zero draws none even if enabled.item.IndicatorWidth = 3; |
| IndicatorLengthPercent | int | 60; 5..100 | Selected bar height as a percentage of item body height.item.IndicatorLengthPercent = 70; |
| ShowFocusCue | bool | true | Draws a focus rectangle for keyboard users.item.ShowFocusCue = true; |
| BadgeText | string | String.Empty | Badge caption; null becomes empty.item.BadgeText = "12"; |
| ShowBadge | bool | false | Shows the badge when text is non-empty; rail mode uses a dot.item.ShowBadge = true; |
| BadgeBackColor | Color | RGB(220,53,69) | Badge/dot background color.item.BadgeBackColor = Color.Crimson; |
| BadgeForeColor | Color | Color.White | Expanded badge text color.item.BadgeForeColor = Color.White; |
| BadgeFont | Font | null | Custom badge font; null uses an automatically derived smaller bold item font.item.BadgeFont = new Font(item.Font.FontFamily, 8f, FontStyle.Bold); |
| Selected | bool | false | Gets/requests selected state through the owner; setting false on its selected item requests a cleared selection.item.Selected = true; |
| Selectable | bool | true | When false, activation still clicks but never selects.signOutItem.Selectable = false; |
| ToolTipText | string | String.Empty | Explicit tooltip; empty falls back to Text.item.ToolTipText = "Open dashboard"; |
| ShowToolTipWhenCollapsed | bool | true | Item-level opt-in/opt-out for sidebar-managed tooltips.item.ShowToolTipWhenCollapsed = false; |
| RailIconAlignment | SiticoneSidebarRailIconAlignment | Center | Centers or retains leading alignment in rail layout.item.RailIconAlignment = SiticoneSidebarRailIconAlignment.Left; |
| OwnerSidebar | SiticoneLeftSidebar | Read only; null | Nearest sidebar ancestor, including through region panels.SiticoneLeftSidebar owner = item.OwnerSidebar; |
| IsRailCollapsed | bool | Read only; false | True when the item has been told to use collapsed rail layout.bool compact = item.IsRailCollapsed; |
| RailAvailableWidth | int | Read only; 0 initially | Latest usable content width reported with rail state.int width = item.RailAvailableWidth; |
| ItemState | SiticoneSidebarItemState | Read only; Normal | Current visual state: disabled, pressed, selected, hovered, or normal.if (item.ItemState == SiticoneSidebarItemState.Selected) { ... } |
| ItemIndex | int | Read only; -1 | Current visual-order index in owner, or -1 when not registered.indexLabel.Text = item.ItemIndex.ToString(); |
Dispose fonts assigned through GlyphFont or BadgeFont when your application no
longer needs them. If BadgeFont is null, the item manages only its own internally derived badge font.
Item events
| Event | Arguments | When it occurs | Example |
|---|---|---|---|
| SelectedChanged | EventArgs | After this item's selected flag changes. | item.SelectedChanged += delegate { UpdateDetails(); }; |
| RailStateChanged | SiticoneSidebarRailEventArgs | After this item changes between full and rail layout. | item.RailStateChanged += Item_RailStateChanged; |
| BadgeChanged | EventArgs | When BadgeText changes to a different value or ShowBadge is assigned. |
item.BadgeChanged += delegate { UpdateUnreadSummary(); }; |
| IconChanged | EventArgs | Whenever Icon is assigned. |
item.IconChanged += delegate { Log("Icon changed"); }; |
| Activated | SiticoneSidebarItemEventArgs | When PerformActivate() runs, including keyboard Enter/Space activation. |
item.Activated += Item_Activated; |
Item methods
| Method | Returns | Behavior | Example |
|---|---|---|---|
| PerformActivate() | void | Raises Activated, selects when selectable/owned, then raises inherited Click. |
item.PerformActivate(); |
| ApplyRailState(bool, bool, int) | void | Implements the rail contract, updates the item layout state, and raises RailStateChanged when the enabled/collapsed flags change. |
item.ApplyRailState(true, true, 52); |
| GetEffectiveToolTipText() | string | Returns explicit ToolTipText, otherwise Text, otherwise empty. |
string tip = item.GetEffectiveToolTipText(); |
private void openDashboardToolStripMenuItem_Click(object sender, EventArgs e)
{
dashboardItem.PerformActivate();
}
Complete enum reference
| Enum | Value | Meaning |
|---|---|---|
| SiticoneSidebarCollapseMode | Width = 0 | Collapse to CollapsedWidth and remain visible. |
| Hide = 1 | Collapse to CollapsedWidth, then hide the control completely. | |
| SiticoneSidebarEasing | Linear = 0 | Constant animation speed. |
| EaseIn = 1 | Starts slowly and accelerates. | |
| EaseOut = 2 | Starts quickly and decelerates. | |
| EaseInOut = 3 | Accelerates then decelerates; the default. | |
| SiticoneSidebarState | Collapsed = 0 | Fully collapsed stable state. |
| Expanded = 1 | Fully expanded stable state. | |
| Animating = 2 | Moving between stable states. | |
| SiticoneSidebarTransition | Collapsing = 0 | A closing transition. |
| Expanding = 1 | An opening transition. | |
| SiticoneSidebarTriggerReason | Code = 0 | Requested by public code/property use. |
| OutsideClick = 1 | Requested by eligible outside-click behavior. | |
| EscapeKey = 2 | Requested by Escape auto-close. | |
| ToggleControl = 3 | Requested by the assigned toggle control. | |
| Hover = 4 | Requested by hover entry or mouse leave. | |
| Designer = 5 | Identifies a design-time request when supplied. | |
| Scrim = 6 | Requested by an accepted scrim click. | |
| KeyboardShortcut = 7 | Requested by the configured toggle shortcut. | |
| PersistedState = 8 | Requested while applying saved state. | |
| ItemActivation = 9 | Selection requested by item activation. | |
| UserResize = 10 | Identifies a user-resize request when supplied. | |
| SiticoneSidebarSide | Left = 0 | Belongs to the left edge; inner features appear on the right. |
| Right = 1 | Belongs to the right edge; inner features appear on the left. | |
| SiticoneSidebarPersistenceMode | ApplicationDataFile = 0 | Uses a small file below per-user application data. |
| Custom = 1 | Application supplies/stores state through persistence events. | |
| SiticoneSidebarRailIconAlignment | Center = 0 | Centers an item's icon in the collapsed rail. |
| Left = 1 | Keeps its leading/left-aligned rail position. | |
| SiticoneSidebarNavigationDirection | Previous = 0 | Move to the previous visible enabled item, wrapping. |
| Next = 1 | Move to the next visible enabled item, wrapping. | |
| First = 2 | Move to the first visible enabled item. | |
| Last = 3 | Move to the last visible enabled item. | |
| SiticoneSidebarItemState | Normal = 0 | Idle enabled item. |
| Hovered = 1 | Pointer is over the item. | |
| Pressed = 2 | Item is currently pressed. | |
| Selected = 3 | Item is the owner's selection. | |
| Disabled = 4 | Inherited Enabled is false. |
ISiticoneSidebarRailAware
The public rail contract contains one method:
void ApplyRailState(bool railModeEnabled, bool collapsed, int availableWidth). A control anywhere
below a sidebar can implement it. The sidebar supplies whether rail mode is enabled, whether compact layout is
currently active, and the usable content width excluding sidebar padding.
public sealed class RailAwareCaption : Label, ISiticoneSidebarRailAware
{
public void ApplyRailState(bool railModeEnabled, bool collapsed, int availableWidth)
{
Visible = !(railModeEnabled && collapsed);
MaximumSize = new Size(Math.Max(0, availableWidth), 0);
}
}
Complete event-argument type reference
Applications normally receive these objects from events rather than constructing them. Their constructors are
public, however, so the signatures are included for complete API coverage and for tests or derived controls.
Types deriving from CancelEventArgs also expose the inherited writable Cancel property.
| Type | Public constructor | Public data |
|---|---|---|
| SiticoneSidebarCancelEventArgs : CancelEventArgs | (transition, reason, currentWidth, targetWidth) |
Transition, Reason, CurrentWidth, TargetWidth, inherited Cancel. |
| SiticoneSidebarEventArgs : EventArgs | (transition, reason, width) |
Transition, Reason, resulting Width. |
| SiticoneSidebarAnimationEventArgs : EventArgs | (transition, fromWidth, toWidth, durationMilliseconds) |
Transition, FromWidth, ToWidth, DurationMilliseconds. |
| SiticoneSidebarAnimationProgressEventArgs : EventArgs | (transition, progress, easedProgress, currentWidth) |
Transition, linear Progress (0..1), EasedProgress (0..1), CurrentWidth. |
| SiticoneSidebarOutsideClickEventArgs : CancelEventArgs | (screenLocation, clickedControl, mouseButtons) |
ScreenLocation, nullable ClickedControl, Button, inherited Cancel. |
| SiticoneSidebarThemeEventArgs : EventArgs | (themeName, backColor, foreColor) |
ThemeName, BackColor, ForeColor. |
| SiticoneSidebarItemEventArgs : EventArgs | (item, index) |
Item, Index (-1 if unregistered), computed ItemText, computed ItemTag. |
| SiticoneSidebarSelectionChangingEventArgs : CancelEventArgs | (previousItem, previousIndex, newItem, newIndex, reason) |
PreviousItem, PreviousIndex, NewItem, NewIndex, Reason, inherited Cancel. Items may be null and indexes -1 when clearing/no prior selection. |
| SiticoneSidebarSelectionChangedEventArgs : EventArgs | (previousItem, previousIndex, selectedItem, selectedIndex, reason) |
PreviousItem, PreviousIndex, SelectedItem, SelectedIndex, Reason, computed SelectedText, computed SelectedTag. |
| SiticoneSidebarItemMouseEventArgs : SiticoneSidebarItemEventArgs | (item, index, button, location, railCollapsed) |
Inherited item data plus Button, item-client Location, and RailCollapsed. |
| SiticoneSidebarToolTipEventArgs : CancelEventArgs | (item, index, text) |
Item, Index, writable Text, inherited Cancel. |
| SiticoneSidebarResizeEventArgs : CancelEventArgs | (originalWidth, currentWidth, proposedWidth, minimumWidth, maximumWidth) |
OriginalWidth, CurrentWidth, writable ProposedWidth, MinimumWidth, MaximumWidth, computed Delta, inherited Cancel. |
| SiticoneSidebarResizeCompletedEventArgs : EventArgs | (originalWidth, finalWidth, cancelled) |
OriginalWidth, FinalWidth, Cancelled, computed Delta. |
| SiticoneSidebarDpiEventArgs : EventArgs | (oldDpi, newDpi, scaleFactor, expandedWidth, collapsedWidth, shadowDepth) |
OldDpi, NewDpi, ScaleFactor, rescaled ExpandedWidth, CollapsedWidth, and ShadowDepth. |
| SiticoneSidebarPersistenceEventArgs : CancelEventArgs | (key, mode, storagePath, state) |
Key, Mode, StoragePath (empty in custom mode), writable State, inherited Cancel. |
| SiticoneSidebarPersistenceCompletedEventArgs : EventArgs | (key, mode, storagePath, state, succeeded, error) |
Key, Mode, StoragePath, State, Succeeded, nullable Error. |
| SiticoneSidebarScrimEventArgs : CancelEventArgs | (scrimBounds, screenLocation, button, opacity) |
Screen ScrimBounds, ScreenLocation, Button, Opacity (0..1), inherited Cancel. |
| SiticoneSidebarScrimVisibilityEventArgs : EventArgs | (visible, scrimBounds, opacity) |
Visible, screen ScrimBounds, Opacity. |
| SiticoneSidebarShortcutEventArgs : CancelEventArgs | (shortcut, willExpand) |
Shortcut, WillExpand, inherited Cancel. |
| SiticoneSidebarNavigationEventArgs : CancelEventArgs | (direction, fromItem, fromIndex, toItem, toIndex, keyData) |
Direction, nullable FromItem, FromIndex, ToItem, ToIndex, KeyData, inherited Cancel. |
| SiticoneSidebarRailEventArgs : EventArgs | (railModeEnabled, collapsed, availableWidth, itemCount) |
RailModeEnabled, Collapsed, AvailableWidth, and ItemCount reporting how many rail-aware descendants were notified. |
| SiticoneSidebarShadowCacheEventArgs : EventArgs | (cacheSize, layerCount, elapsedMilliseconds) |
CacheSize, LayerCount, ElapsedMilliseconds. |
| SiticoneSidebarSideChangedEventArgs : EventArgs | (oldSide, newSide, dockStyle) |
OldSide, NewSide, resulting DockStyle (possibly None when app-managed). |
| SiticoneSidebarRegionEventArgs : EventArgs | (header, content, footer, enabled) |
HeaderPanel, ContentPanel, FooterPanel, Enabled. |
SiticoneSidebarCancelEventArgs args = new SiticoneSidebarCancelEventArgs(
SiticoneSidebarTransition.Collapsing,
SiticoneSidebarTriggerReason.Code,
260,
60);
args.Cancel = true;
Assert.IsTrue(args.Cancel);
Assert.AreEqual(260, args.CurrentWidth);
Assert.AreEqual(60, args.TargetWidth);
Conditional design-time API
The supplied source places the designer classes inside #if !NETCOREAPP. They are therefore public
only in the build where the source compiles its .NET Framework System.Design support. End users
normally interact with these members through the Smart Tag instead of constructing the classes directly.
SiticoneLeftSidebarDesigner public members
| Member | Purpose |
|---|---|
| ActionLists | Overridden read-only property returning a collection containing a SiticoneLeftSidebarActionList. |
| Initialize(IComponent component) | Initializes parent-control design support and, when regions are enabled, makes header/content/footer panels designer drop targets. |
SiticoneLeftSidebarActionList constructor and wrapped properties
Constructor: SiticoneLeftSidebarActionList(IComponent component). It enables automatic
Smart Tag display for the newly dropped component. Its public wrapped properties delegate to the
matching sidebar properties through design-time property descriptors.
| Wrapped property | Type | Smart Tag area |
|---|---|---|
| EnableDropShadow | bool | Drop Shadow |
| ShadowDepth | int | Drop Shadow |
| ShadowColor | Color | Drop Shadow |
| CacheShadow | bool | Drop Shadow |
| RightBorderThickness | int | Border |
| RightBorderColor | Color | Border |
| AutoCloseOnOutsideClick | bool | Behavior |
| AutoCloseOnEscape | bool | Behavior |
| ExpandOnHover | bool | Behavior |
| IsExpanded | bool | Layout |
| ExpandedWidth | int | Layout |
| CollapsedWidth | int | Layout |
| CollapseMode | SiticoneSidebarCollapseMode | Layout |
| SidebarSide | SiticoneSidebarSide | Layout |
| EnableAnimation | bool | Animation |
| AnimationDuration | int | Animation |
| AnimationEasing | SiticoneSidebarEasing | Animation |
| EnableGradient | bool | Themes |
| CornerRadius | int | Border |
| EnableIconRailMode | bool | Icon Rail |
| EnableCollapsedToolTips | bool | Icon Rail |
| EnableScrim | bool | Overlay |
| ScrimOpacity | int | Overlay |
| EnableUserResize | bool | User Resize |
| MinExpandedWidth | int | User Resize |
| MaxExpandedWidth | int | User Resize |
| EnablePersistence | bool | Behavior |
| EnableDpiScaling | bool | Display |
| EnableKeyboardNavigation | bool | Behavior |
| EnableRegions | bool | Layout |
SiticoneLeftSidebarActionList public actions and methods
| Method | Exact action |
|---|---|
| ExpandSidebar() | Sets IsExpanded = true through the designer. |
| CollapseSidebar() | Sets IsExpanded = false. |
| ToggleSidebar() | Inverts the current design-time expanded value. |
| CaptureCurrentWidth() | Copies the current control width into ExpandedWidth. |
| DockToLeft() | Sets SidebarSide.Left. |
| DockToRight() | Sets SidebarSide.Right. |
| ApplyIconRailPreset() | Enables icon rail and collapsed tooltips, sets collapsed width to 56, and keeps children visible for rail rendering. |
| ApplyDrawerPreset() | Enables scrim, outside-click close, Escape close, and bring-to-front on expand. |
| ApplyDefaultTheme() | White background; RGB(60,60,60) foreground. |
| ApplyDarkTheme() | RGB(45,45,48) background; white foreground. |
| ApplyBlueTheme() | DodgerBlue background; white foreground. |
| ApplyGreenTheme() | SeaGreen background; white foreground. |
| ApplyRedTheme() | Crimson background; white foreground. |
| ApplyOrangeTheme() | Orange background; black foreground. |
| ApplyPurpleTheme() | MediumPurple background; white foreground. |
| ApplyGrayTheme() | LightGray background; black foreground. |
| ApplyMidnightTheme() | RGB(17,24,39) background; RGB(229,231,235) foreground. |
| ApplySlateTheme() | RGB(248,250,252) background; RGB(51,65,85) foreground. |
| CopySettings() | Copies browsable writable customization except identity, position/size, controls, toggle wiring, and persistence key. |
| PasteSettings() | Applies a previously copied setting buffer to compatible browsable writable properties. |
| GetSortedActionItems() | Builds and returns the complete grouped Smart Tag menu. |
Complete configuration recipes
Recipe: desktop rail that expands on click
private void ConfigureDesktopRail()
{
sidebar.SidebarSide = SiticoneSidebarSide.Left;
sidebar.ExpandedWidth = 264;
sidebar.CollapsedWidth = 64;
sidebar.CollapseMode = SiticoneSidebarCollapseMode.Width;
sidebar.EnableIconRailMode = true;
sidebar.EnableCollapsedToolTips = true;
sidebar.ToggleControl = menuButton;
sidebar.EnableAnimation = true;
sidebar.AnimationDuration = 200;
sidebar.AnimationEasing = SiticoneSidebarEasing.EaseInOut;
sidebar.EnablePersistence = true;
sidebar.PersistenceKey = "DesktopMainNavigation";
sidebar.PersistExpandedState = true;
sidebar.PersistWidth = false;
}
Recipe: modal mobile-style drawer
private void ConfigureModalDrawer()
{
sidebar.ExpandedWidth = 300;
sidebar.CollapsedWidth = 0;
sidebar.CollapseMode = SiticoneSidebarCollapseMode.Hide;
sidebar.BringToFrontOnExpand = true;
sidebar.EnableScrim = true;
sidebar.ScrimOpacity = 40;
sidebar.ScrimClosesSidebar = true;
sidebar.AutoCloseOnOutsideClick = true;
sidebar.AutoCloseOnEscape = true;
sidebar.ToggleControl = menuButton;
sidebar.Collapse(false);
}
Recipe: fixed navigation with no collapsing
private void ConfigureFixedSidebar()
{
sidebar.ExpandedWidth = 240;
sidebar.EnableAnimation = false;
sidebar.EnableIconRailMode = false;
sidebar.AutoCloseOnOutsideClick = false;
sidebar.AutoCloseOnEscape = false;
sidebar.Expand(false);
}
Recipe: resizable, keyboard-friendly admin navigation
private void ConfigureAdminNavigation()
{
sidebar.EnableRegions = true;
sidebar.HeaderHeight = 72;
sidebar.FooterHeight = 64;
sidebar.EnableUserResize = true;
sidebar.MinExpandedWidth = 220;
sidebar.MaxExpandedWidth = 440;
sidebar.EnableKeyboardNavigation = true;
sidebar.ToggleShortcut = Keys.Control | Keys.B;
sidebar.AutoCloseOnEscape = true;
sidebar.PersistenceKey = "AdminNavigation";
sidebar.PersistExpandedState = true;
sidebar.PersistWidth = true;
sidebar.PersistSelectedIndex = true;
sidebar.EnablePersistence = true;
}
Troubleshooting and reliable-use checklist
The sidebar toggles twice or appears not to move
If ToggleControl is assigned, the sidebar already subscribes to that control's click.
Remove any additional click handler that also calls Toggle(). One click otherwise requests
two opposite transitions.
Animation looks wrong or an old Timer is still present
Remove custom width-changing timers. Configure EnableAnimation,
AnimationDuration, and AnimationEasing, then use the public state methods.
Manually changing Width during the built-in transition competes with the requested target.
The control's MinimumSize is wider than CollapsedWidth
Do not change MinimumSize merely to make normal collapsing work. The supplied control handles
the width constraint during its transition and restores the wider constraint when appropriate.
Rail mode does not activate
- Set
EnableIconRailMode = true. - Check that the current
Widthis at or belowEffectiveRailSwitchWidth. - Use
RailSwitchWidth = 0forCollapsedWidth + 24, or set an explicit positive threshold. - Call
RefreshItems()after an unusual batch of manual layout changes.
A collapsed tooltip does not appear
- Confirm
EnableCollapsedToolTipsandIsRailCollapsedare both true. - Confirm the item has
ShowToolTipWhenCollapsed = true. - Give the item either
ToolTipTextor a non-emptyText. - Check whether
ItemToolTipShowingcancels or replaces the text with empty.
Outside-click close does not happen
- Confirm
AutoCloseOnOutsideClick = trueand the sidebar is expanded, stable, and not being resized. - Clicks inside the sidebar, inside
ToggleControl, or inside registered exceptions are intentionally ignored. - Title-bar/non-client clicks require
AutoCloseOnTitleBarClick = true. - Native popup windows that do not resolve to a managed WinForms control are not treated as ordinary outside controls.
- Check whether
OutsideClickedsetsCancel = true.
The scrim is not visible
Confirm EnableScrim, a visible owning form, an expanded visible sidebar, and non-empty form
space beside it. CalculateScrimBounds() helps diagnose the available area. A zero opacity is
technically enabled but visually transparent.
State does not restore
- Set persistence options and wire custom events before the control is created, or call
LoadState()manually afterward. - Use a stable, unique
PersistenceKey. - Add items before loading when selected-index persistence is enabled.
- In custom mode, assign saved text to
StateLoading's writableState. - Inspect
StateLoaded.SucceededandError; remember that no stored state makesLoadState()return false without necessarily being an error.
An item clicks but does not select
Check Selectable, ItemSelectionChanging.Cancel, and whether the item is registered.
Non-selectable items are designed to remain clickable without changing the selected page.
HeaderPanel, ContentPanel, or FooterPanel is null
Set EnableRegions = true first. If enabling regions after direct children already exist,
decide whether MoveExistingChildrenToContent should be true before enabling.
The resize grip does not drag
Resizing starts only while EnableUserResize is true and the sidebar is expanded, not
animating, and running outside the designer. Use GetResizeGripBounds() to confirm the inner
edge and ensure UserResizeStarted does not cancel.
RightBorder sounds incorrect on a right sidebar
The original property names remain for compatibility, but the visual edge mirrors correctly. Use
EdgeBorderThickness and EdgeBorderColor in code when neutral naming is clearer.
The Smart Tag designer is absent on a modern .NET target
The supplied source compiles the System.Design-based designer classes only when
NETCOREAPP is not defined. Configure the same runtime properties in the Properties window or
in code; the runtime sidebar feature set is not removed.
- Call control members on the WinForms UI thread.
- Use one state mechanism: the built-in methods/properties, not a competing width timer.
- Give each persistent sidebar a stable key and build its items before restoring a selected index.
- Use cancellable events for validation and completion events for work that requires the final layout.
- Dispose application-created images/fonts according to your application's ownership policy; removing an item disposes the item itself.
- Test both side orientations, high DPI, keyboard-only use, collapsed rail, and the smallest supported form size.