BeepAccordionMenu
Collapsible navigation control with hierarchical menu structure and smooth animations
📑 Table of Contents
Overview
BeepAccordionMenu is a sophisticated collapsible navigation control that provides hierarchical menu organization with smooth expand/collapse animations. It features both expanded and collapsed states, making it perfect for sidebar navigation, dashboard menus, and space-efficient navigation systems.
Built on the BeepControl foundation, BeepAccordionMenu supports nested menu items, SVG icons, custom theming, smooth animations, and intelligent hit testing. The control can display in both expanded mode (showing full text and hierarchy) and collapsed mode (showing only icons), making it ideal for responsive layouts.
Key Features
🔄 Expand/Collapse Animation
Smooth animated transitions between expanded and collapsed states with customizable speed
🌳 Hierarchical Structure
Support for nested menu items with parent-child relationships and visual connectors
🖼️ Icon Support
SVG and bitmap icon support with theme-aware coloring and adaptive sizing
🎯 Smart Hit Testing
Advanced hit testing for precise click detection on items, expand/collapse buttons
📱 Responsive Design
Automatic layout adjustment for both desktop and space-constrained environments
🎨 Rich Visual States
Hover effects, selection indicators, and visual feedback for user interactions
Visual Preview
BeepAccordionMenu in expanded (left) and collapsed (right) states
Basic Usage
Simple Navigation Menu
// Create the accordion menu
var navigationMenu = new BeepAccordionMenu
{
Size = new Size(200, 400),
Location = new Point(10, 10),
Title = "Navigation",
ExpandedWidth = 200,
CollapsedWidth = 64,
ItemHeight = 40,
ChildItemHeight = 30
};
// Add main menu items
var dashboardItem = new SimpleItem
{
Text = "Dashboard",
ImagePath = "dashboard.svg"
};
// Add child items to dashboard
dashboardItem.Children.Add(new SimpleItem { Text = "Analytics", ImagePath = "analytics.svg" });
dashboardItem.Children.Add(new SimpleItem { Text = "Reports", ImagePath = "reports.svg" });
dashboardItem.Children.Add(new SimpleItem { Text = "Overview", ImagePath = "overview.svg" });
navigationMenu.ListItems.Add(dashboardItem);
// Add other menu items
navigationMenu.ListItems.Add(new SimpleItem
{
Text = "Projects",
ImagePath = "projects.svg"
});
navigationMenu.ListItems.Add(new SimpleItem
{
Text = "Settings",
ImagePath = "settings.svg"
});
// Handle menu clicks
navigationMenu.ItemClick += (sender, e) =>
{
MessageBox.Show($"Clicked: {e.ItemText}");
};
// Handle toggle events
navigationMenu.ToggleClicked += (sender, e) =>
{
// Console.WriteLine($"Menu toggled: {(bool)e.Item}");
};
this.Controls.Add(navigationMenu);
Multi-Level Hierarchical Menu
var hierarchicalMenu = new BeepAccordionMenu
{
Size = new Size(220, 500),
Title = "File Explorer",
ItemHeight = 35,
ChildItemHeight = 28,
IndentationWidth = 25
};
// Create a complex hierarchy
var documentsItem = new SimpleItem
{
Text = "Documents",
ImagePath = "folder.svg"
};
// Add nested folders
var projectsFolder = new SimpleItem { Text = "Projects", ImagePath = "folder.svg" };
projectsFolder.Children.Add(new SimpleItem { Text = "Project A", ImagePath = "file.svg" });
projectsFolder.Children.Add(new SimpleItem { Text = "Project B", ImagePath = "file.svg" });
var reportsFolder = new SimpleItem { Text = "Reports", ImagePath = "folder.svg" };
reportsFolder.Children.Add(new SimpleItem { Text = "Annual Report", ImagePath = "pdf.svg" });
reportsFolder.Children.Add(new SimpleItem { Text = "Monthly Stats", ImagePath = "excel.svg" });
documentsItem.Children.Add(projectsFolder);
documentsItem.Children.Add(reportsFolder);
documentsItem.Children.Add(new SimpleItem { Text = "README.txt", ImagePath = "text.svg" });
hierarchicalMenu.ListItems.Add(documentsItem);
// Add more root items
hierarchicalMenu.ListItems.Add(new SimpleItem
{
Text = "Downloads",
ImagePath = "download.svg"
});
hierarchicalMenu.ListItems.Add(new SimpleItem
{
Text = "Pictures",
ImagePath = "image.svg"
});
this.Controls.Add(hierarchicalMenu);
Use SimpleItem's Children collection to create hierarchical menus that automatically support expand/collapse functionality with smooth animations.
Properties
Layout Properties
| Property | Type | Default | Description |
|---|---|---|---|
ExpandedWidth |
int | 200 | Width of the accordion when fully expanded |
CollapsedWidth |
int | 64 | Width of the accordion when collapsed |
ItemHeight |
int | 40 | Height of main menu items |
ChildItemHeight |
int | 30 | Height of child/sub menu items |
IndentationWidth |
int | 20 | Indentation space for child items |
Animation Properties
| Property | Type | Default | Description |
|---|---|---|---|
AnimationStep |
int | 20 | Number of pixels to animate per step |
AnimationDelay |
int | 15 | Delay between animation steps in milliseconds |
Data Properties
ListItems BindingList<SimpleItem>
Collection of menu items to display
Title string
Title displayed in the header area
SelectedItem SimpleItem
Currently selected menu item
IsRounded bool
Enable rounded corners for modern appearance
Events
| Event | Parameters | Description |
|---|---|---|
ItemClick |
object sender, BeepMouseEventArgs e | Fired when a menu item is clicked |
ToggleClicked |
object sender, BeepMouseEventArgs e | Fired when the expand/collapse toggle button is clicked |
HeaderExpandedChanged |
object sender, BeepMouseEventArgs e | Fired when a header item's expanded state changes |
Event Handling Examples
var accordionMenu = new BeepAccordionMenu();
// Handle menu item clicks
accordionMenu.ItemClick += (sender, e) =>
{
var clickedItem = e.Item as SimpleItem;
// Console.WriteLine($"Menu item clicked: {e.ItemText}");
// Handle navigation based on the clicked item
HandleNavigation(clickedItem);
// Update UI state
UpdateActiveView(clickedItem.Text);
};
// Handle toggle button clicks
accordionMenu.ToggleClicked += (sender, e) =>
{
bool isCollapsed = (bool)e.Item;
// Console.WriteLine($"Menu toggled. Collapsed: {isCollapsed}");
// Adjust layout for other controls
AdjustLayoutForMenuState(isCollapsed);
// Save user preference
Settings.Default.MenuCollapsed = isCollapsed;
Settings.Default.Save();
};
// Handle header expansion changes
accordionMenu.HeaderExpandedChanged += (sender, e) =>
{
var headerItem = e.Item as SimpleItem;
// Console.WriteLine($"Header '{e.ItemText}' expansion changed");
// Save expansion state for persistence
SaveMenuExpansionState(headerItem);
};
Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
ApplyTheme |
None | void | Apply current theme colors and fonts to the accordion |
Draw |
Graphics graphics, Rectangle rectangle | void | Custom drawing method for rendering the accordion |
Method Usage Examples
// Apply theme changes
accordionMenu.Theme = "DarkTheme";
accordionMenu.ApplyTheme();
// Custom drawing (typically handled internally)
protected override void OnPaint(PaintEventArgs e)
{
accordionMenu.Draw(e.Graphics, accordionMenu.ClientRectangle);
}
Examples
Dashboard Sidebar
public class DashboardForm : Form
{
private BeepAccordionMenu sidebarMenu;
private Panel mainContentPanel;
public DashboardForm()
{
InitializeForm();
SetupSidebarMenu();
SetupMainContent();
}
private void SetupSidebarMenu()
{
sidebarMenu = new BeepAccordionMenu
{
Dock = DockStyle.Left,
Width = 200,
Title = "Dashboard",
Theme = "DarkTheme",
ItemHeight = 45,
ChildItemHeight = 35,
ExpandedWidth = 200,
CollapsedWidth = 60
};
// Create dashboard section
var dashboardSection = new SimpleItem
{
Text = "Analytics",
ImagePath = "analytics.svg"
};
dashboardSection.Children.Add(new SimpleItem { Text = "Overview", ImagePath = "overview.svg" });
dashboardSection.Children.Add(new SimpleItem { Text = "Performance", ImagePath = "performance.svg" });
dashboardSection.Children.Add(new SimpleItem { Text = "Reports", ImagePath = "reports.svg" });
// Create projects section
var projectsSection = new SimpleItem
{
Text = "Projects",
ImagePath = "projects.svg"
};
projectsSection.Children.Add(new SimpleItem { Text = "Active Projects", ImagePath = "active.svg" });
projectsSection.Children.Add(new SimpleItem { Text = "Completed", ImagePath = "completed.svg" });
projectsSection.Children.Add(new SimpleItem { Text = "Archived", ImagePath = "archive.svg" });
// Add sections to menu
sidebarMenu.ListItems.Add(dashboardSection);
sidebarMenu.ListItems.Add(projectsSection);
// Handle menu events
sidebarMenu.ItemClick += OnMenuItemClick;
sidebarMenu.ToggleClicked += OnMenuToggle;
this.Controls.Add(sidebarMenu);
}
private void OnMenuItemClick(object sender, BeepMouseEventArgs e)
{
var clickedItem = e.Item as SimpleItem;
// Navigate to appropriate view
switch (clickedItem.Text)
{
case "Overview":
ShowDashboardOverview();
break;
case "Performance":
ShowPerformanceView();
break;
case "Reports":
ShowReportsView();
break;
case "Active Projects":
ShowActiveProjects();
break;
default:
ShowGenericView(clickedItem.Text);
break;
}
}
private void OnMenuToggle(object sender, BeepMouseEventArgs e)
{
bool isCollapsed = (bool)e.Item;
// Save user preference
Properties.Settings.Default.SidebarCollapsed = isCollapsed;
Properties.Settings.Default.Save();
}
}
File Explorer Menu
public class FileExplorerForm : Form
{
private BeepAccordionMenu folderTreeMenu;
private ListView fileListView;
private void LoadFolderStructure()
{
try
{
// Get drives
var drives = DriveInfo.GetDrives();
foreach (var drive in drives.Where(d => d.IsReady))
{
var driveItem = new SimpleItem
{
Text = $"{drive.Name} ({drive.DriveType})",
ImagePath = "drive.svg",
Tag = drive.RootDirectory.FullName
};
// Load top-level folders
LoadSubFolders(driveItem, drive.RootDirectory, 2);
folderTreeMenu.ListItems.Add(driveItem);
}
}
catch (Exception ex)
{
MessageBox.Show($"Error loading folder structure: {ex.Message}");
}
}
private void LoadSubFolders(SimpleItem parentItem, DirectoryInfo directory, int maxDepth)
{
if (maxDepth <= 0) return;
try
{
var subDirectories = directory.GetDirectories()
.Where(d => !d.Attributes.HasFlag(FileAttributes.Hidden))
.Take(20);
foreach (var subDir in subDirectories)
{
var folderItem = new SimpleItem
{
Text = subDir.Name,
ImagePath = "folder.svg",
Tag = subDir.FullName
};
LoadSubFolders(folderItem, subDir, maxDepth - 1);
parentItem.Children.Add(folderItem);
}
}
catch (UnauthorizedAccessException)
{
// Skip folders we can't access
}
}
}
Theming
BeepAccordionMenu provides comprehensive theming with automatic application of theme colors and fonts:
Theme Application
var accordionMenu = new BeepAccordionMenu
{
Theme = "DarkTheme",
UseThemeFont = true,
IsRounded = true,
ShowShadow = true
};
// Apply theme manually if needed
accordionMenu.ApplyTheme();
// Theme automatically applies:
// - SideMenuBackColor: Main accordion background
// - SideMenuForeColor: Text and icon colors
// - MenuMainItemHoverBackColor: Item hover background
// - MenuMainItemHoverForeColor: Item hover text color
// - MenuMainItemSelectedBackColor: Selected item background
Theme-Responsive Properties
- Background colors - Automatically use theme background colors
- Text colors - Adapt to theme foreground colors
- Hover states - Use theme hover colors for interactive feedback
- Selection states - Apply theme selection colors
- Icon coloring - SVG icons adapt to theme colors
Best Practices
🏗️ Structure Design
- Logical grouping: Group related items under common headers for intuitive navigation
- Depth limitation: Keep hierarchy shallow (2-3 levels max) to avoid complexity
- Clear labeling: Use descriptive, concise names for all menu items
- Consistent iconography: Use consistent icon styles and meanings throughout
🎨 Visual Design
- Appropriate sizing: Choose item heights that are touch-friendly (40px+ for main items)
- Visual hierarchy: Use different sizes for parent vs child items to show relationships
- Color consistency: Maintain consistent color usage for states and categories
- Icon quality: Use high-quality SVG icons that scale well at different sizes
⚡ Performance
- Lazy loading: Load menu items dynamically for large hierarchies
- Animation settings: Adjust animation speed based on user preferences
- Memory management: Dispose of event handlers when removing items
- Icon optimization: Cache frequently used icons to improve performance
♿ Accessibility
- Keyboard navigation: Ensure accordion works with keyboard input
- Screen readers: Provide appropriate ARIA labels and descriptions
- High contrast: Ensure good contrast ratios for all theme variations
- Focus indicators: Provide clear visual focus indicators
Use the HeaderExpandedChanged event to save user preferences for menu expansion states, providing a consistent experience across application sessions.
BeepAccordionMenu provides smooth animations and hierarchical organization, making it perfect for navigation sidebars, file explorers, and settings panels.
Avoid creating menus that are too deep (more than 3 levels) as this can confuse users and make navigation difficult, especially in collapsed mode.