BeepBreadcrumps
Enhanced navigation breadcrumb control with multiple visual styles and interactive features
📑 Table of Contents
Overview
BeepBreadcrumps is an advanced navigation breadcrumb control that provides users with clear visual guidance about their current location within a hierarchical structure. It offers multiple visual styles, interactive click handling, and comprehensive theming support.
Built on the BeepControl foundation, BeepBreadcrumps features hover effects, customizable separators, icon support, multiple visual styles (Classic, Modern, Pill, Flat), and complete theme integration. It's perfect for file explorers, website navigation, application menus, and any hierarchical navigation system.
Key Features
🎨 Multiple Visual Styles
Classic, Modern, Pill, and Flat styles to match any design aesthetic
🖱️ Interactive Navigation
Clickable breadcrumb items with hover effects and visual feedback
🖼️ Icon Support
Optional SVG icons for each breadcrumb item with theme-aware coloring
🔗 Customizable Separators
Configurable separator text and spacing between breadcrumb items
📱 Responsive Design
Automatic layout adjustment and item positioning based on content
🎯 Hit Area Testing
Advanced hit testing for precise click detection and hover handling
Visual Preview
Examples of BeepBreadcrumps with different visual styles
Basic Usage
Simple Breadcrumb Navigation
// Create a basic breadcrumb control
var breadcrumbs = new BeepBreadcrumps
{
Size = new Size(500, 36),
Location = new Point(10, 10),
Style = BreadcrumbStyle.Modern,
SeparatorText = ">",
ItemSpacing = 8,
ShowIcons = true
};
// Add navigation items
breadcrumbs.Items.Add(new SimpleItem
{
Name = "Home",
Text = "Home",
ImagePath = "home.svg"
});
breadcrumbs.Items.Add(new SimpleItem
{
Name = "Documents",
Text = "Documents",
ImagePath = "folder.svg"
});
breadcrumbs.Items.Add(new SimpleItem
{
Name = "Projects",
Text = "Projects",
ImagePath = "folder.svg"
});
breadcrumbs.Items.Add(new SimpleItem
{
Name = "CurrentFile",
Text = "Current File",
ImagePath = "file.svg"
});
// Handle breadcrumb clicks
breadcrumbs.CrumbClicked += (sender, e) =>
{
MessageBox.Show($"Navigating to: {e.ItemText} (Index: {e.Index})");
};
this.Controls.Add(breadcrumbs);
File Explorer Breadcrumbs
var filePathBreadcrumbs = new BeepBreadcrumps
{
Size = new Size(600, 40),
Location = new Point(10, 10),
Style = BreadcrumbStyle.Classic,
SeparatorText = "/",
ItemSpacing = 12,
ShowIcons = true,
ShowHomeIcon = true
};
// Handle navigation clicks
filePathBreadcrumbs.CrumbClicked += OnPathClicked;
this.Controls.Add(filePathBreadcrumbs);
private void OnPathClicked(object sender, CrumbClickedEventArgs e)
{
// Navigate to the selected path level
NavigateToPath(e.Index);
}
Website Navigation Breadcrumbs
var websiteBreadcrumbs = new BeepBreadcrumps
{
Size = new Size(700, 38),
Style = BreadcrumbStyle.Pill,
SeparatorText = "?",
ItemSpacing = 6,
ShowIcons = false
};
// Add website navigation structure
websiteBreadcrumbs.AddItem("home", "Home");
websiteBreadcrumbs.AddItem("products", "Products");
websiteBreadcrumbs.AddItem("electronics", "Electronics");
websiteBreadcrumbs.AddItem("laptops", "Laptops");
websiteBreadcrumbs.AddItem("gaming", "Gaming Laptops");
// Set current selection
websiteBreadcrumbs.SelectedIndex = 4;
Properties
Core Properties
| Property | Type | Default | Description |
|---|---|---|---|
Items |
BindingList<SimpleItem> | Empty list | Collection of breadcrumb navigation items |
SelectedItem |
SimpleItem | null | Currently selected breadcrumb item (read-only) |
SelectedIndex |
int | -1 | Index of currently selected breadcrumb item (read-only) |
Appearance Properties
| Property | Type | Default | Description |
|---|---|---|---|
Style |
BreadcrumbStyle | Modern | Visual style: Classic, Modern, Pill, or Flat |
TextFont |
Font | Segoe UI, 9pt | Font used for breadcrumb item text |
SeparatorText |
string | ">" | Text displayed between breadcrumb items |
ItemSpacing |
int | 8 | Spacing in pixels between breadcrumb items |
ShowIcons |
bool | true | Whether to display icons for breadcrumb items |
ShowHomeIcon |
bool | true | Whether to display a home icon for the first item |
Inherited Properties
BeepBreadcrumps inherits all properties from BeepControl, including:
- Theme - Theme name for styling
- IsRounded - Enable rounded corners
- ShowShadow - Display drop shadow
- BorderRadius - Corner radius size
- UseThemeFont - Apply theme fonts automatically
Events
| Event | Parameters | Description |
|---|---|---|
CrumbClicked |
object sender, CrumbClickedEventArgs e | Fired when user clicks on a breadcrumb item |
CrumbClickedEventArgs Properties
| Property | Type | Description |
|---|---|---|
Index |
int | Index of the clicked breadcrumb item |
ItemName |
string | Name property of the clicked item |
ItemText |
string | Display text of the clicked item |
Event Handling Example
var breadcrumbs = new BeepBreadcrumps();
// Handle breadcrumb navigation
breadcrumbs.CrumbClicked += (sender, e) =>
{
// Console.WriteLine($"Clicked item: {e.ItemText}");
// Console.WriteLine($"Index: {e.Index}");
// Console.WriteLine($"Name: {e.ItemName}");
// Navigate to the selected level
NavigateToLevel(e.Index, e.ItemName);
};
private void NavigateToLevel(int index, string itemName)
{
// Remove all items after the clicked index
breadcrumbs.NavigateToIndex(index);
// Perform navigation logic
switch (itemName)
{
case "Home":
ShowHomePage();
break;
case "Documents":
ShowDocumentsPage();
break;
case "Projects":
ShowProjectsPage();
break;
}
}
Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
AddItem |
string name, string text, string imagePath | void | Add a new breadcrumb item to the collection |
RemoveItem |
int index | void | Remove a breadcrumb item at the specified index |
Clear |
None | void | Remove all breadcrumb items |
NavigateToIndex |
int index | void | Navigate to specific index and remove all items after it |
ApplyTheme |
None | void | Apply current theme colors and fonts to the breadcrumbs |
Method Usage Examples
// Add items dynamically
breadcrumbs.AddItem("users", "Users", "users.svg");
breadcrumbs.AddItem("profile", "Profile", "user.svg");
// Navigate backwards (removes items after index 1)
breadcrumbs.NavigateToIndex(1);
// Remove specific item
breadcrumbs.RemoveItem(2);
// Clear all breadcrumbs
breadcrumbs.Clear();
// Apply theme changes
breadcrumbs.Theme = "DarkTheme";
breadcrumbs.ApplyTheme();
Examples
File System Explorer
public class FileExplorerForm : Form
{
private BeepBreadcrumps pathBreadcrumbs;
private BeepListBox fileListBox;
private string currentPath;
public FileExplorerForm()
{
InitializeFileExplorer();
LoadInitialPath(@"C:\");
}
private void InitializeFileExplorer()
{
this.Text = "File Explorer";
this.Size = new Size(800, 600);
// Path breadcrumbs
pathBreadcrumbs = new BeepBreadcrumps
{
Size = new Size(780, 40),
Location = new Point(10, 10),
Style = BreadcrumbStyle.Classic,
SeparatorText = "\\",
ItemSpacing = 4,
ShowIcons = true
};
pathBreadcrumbs.CrumbClicked += OnPathBreadcrumbClicked;
// File list
fileListBox = new BeepListBox
{
Size = new Size(780, 520),
Location = new Point(10, 60)
};
fileListBox.ItemDoubleClicked += OnFileDoubleClicked;
this.Controls.AddRange(new Control[] { pathBreadcrumbs, fileListBox });
}
private void LoadInitialPath(string path)
{
currentPath = path;
UpdateBreadcrumbs();
LoadDirectoryContents();
}
private void UpdateBreadcrumbs()
{
pathBreadcrumbs.Clear();
if (string.IsNullOrEmpty(currentPath))
return;
var pathParts = currentPath.Split(new char[] { '\\', '/' },
StringSplitOptions.RemoveEmptyEntries);
// Add root drive
if (currentPath.StartsWith(@"C:\"))
{
pathBreadcrumbs.AddItem("C:", "C:", "drive.svg");
}
// Add each directory level
string buildPath = @"C:\";
for (int i = 0; i < pathParts.Length; i++)
{
if (pathParts[i] == "C:")
continue;
buildPath = Path.Combine(buildPath, pathParts[i]);
pathBreadcrumbs.AddItem(buildPath, pathParts[i], "folder.svg");
}
// Set selection to last item
if (pathBreadcrumbs.Items.Count > 0)
{
pathBreadcrumbs.SelectedIndex = pathBreadcrumbs.Items.Count - 1;
}
}
private void LoadDirectoryContents()
{
try
{
fileListBox.Items.Clear();
if (!Directory.Exists(currentPath))
return;
// Add directories
var directories = Directory.GetDirectories(currentPath);
foreach (var dir in directories)
{
var dirInfo = new DirectoryInfo(dir);
fileListBox.Items.Add(new SimpleItem
{
Name = dirInfo.FullName,
Text = dirInfo.Name,
ImagePath = "folder.svg"
});
}
// Add files
var files = Directory.GetFiles(currentPath);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
fileListBox.Items.Add(new SimpleItem
{
Name = fileInfo.FullName,
Text = fileInfo.Name,
ImagePath = GetFileIcon(fileInfo.Extension)
});
}
}
catch (Exception ex)
{
MessageBox.Show($"Error loading directory: {ex.Message}",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void OnPathBreadcrumbClicked(object sender, CrumbClickedEventArgs e)
{
// Navigate to the clicked path level
var clickedItem = pathBreadcrumbs.Items[e.Index];
currentPath = clickedItem.Name;
// Remove items after clicked index
pathBreadcrumbs.NavigateToIndex(e.Index);
// Reload directory contents
LoadDirectoryContents();
}
private void OnFileDoubleClicked(object sender, SimpleItem item)
{
string fullPath = item.Name;
if (Directory.Exists(fullPath))
{
// Navigate into directory
currentPath = fullPath;
UpdateBreadcrumbs();
LoadDirectoryContents();
}
else if (File.Exists(fullPath))
{
// Open file
try
{
Process.Start(new ProcessStartInfo
{
FileName = fullPath,
UseShellExecute = true
});
}
catch (Exception ex)
{
MessageBox.Show($"Error opening file: {ex.Message}",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private string GetFileIcon(string extension)
{
return extension.ToLower() switch
{
".txt" => "file-text.svg",
".pdf" => "file-pdf.svg",
".jpg" or ".jpeg" or ".png" or ".gif" => "file-image.svg",
".exe" => "file-exe.svg",
".zip" or ".rar" => "file-archive.svg",
_ => "file.svg"
};
}
}
Website Navigation Breadcrumbs
public class WebsiteNavigationControl : UserControl
{
private BeepBreadcrumps navigationBreadcrumbs;
private Dictionary pageHierarchy;
public event EventHandler PageNavigationRequested;
public WebsiteNavigationControl()
{
InitializeNavigation();
SetupPageHierarchy();
}
private void InitializeNavigation()
{
navigationBreadcrumbs = new BeepBreadcrumps
{
Size = new Size(700, 42),
Location = new Point(0, 0),
Style = BreadcrumbStyle.Modern,
SeparatorText = "❯",
ItemSpacing = 10,
ShowIcons = true,
Dock = DockStyle.Fill
};
navigationBreadcrumbs.CrumbClicked += OnNavigationClicked;
this.Controls.Add(navigationBreadcrumbs);
}
private void SetupPageHierarchy()
{
pageHierarchy = new Dictionary
{
["home"] = new PageInfo { Title = "Home", Icon = "home.svg", Parent = null },
["products"] = new PageInfo { Title = "Products", Icon = "box.svg", Parent = "home" },
["electronics"] = new PageInfo { Title = "Electronics", Icon = "chip.svg", Parent = "products" },
["computers"] = new PageInfo { Title = "Computers", Icon = "monitor.svg", Parent = "electronics" },
["laptops"] = new PageInfo { Title = "Laptops", Icon = "laptop.svg", Parent = "computers" },
["gaming"] = new PageInfo { Title = "Gaming", Icon = "gamepad.svg", Parent = "laptops" }
};
}
public void NavigateToPage(string pageId)
{
if (!pageHierarchy.ContainsKey(pageId))
return;
// Build breadcrumb trail
var trail = BuildBreadcrumbTrail(pageId);
// Update breadcrumbs
navigationBreadcrumbs.Clear();
foreach (var page in trail)
{
navigationBreadcrumbs.AddItem(
page,
pageHierarchy[page].Title,
pageHierarchy[page].Icon
);
}
// Set current selection
navigationBreadcrumbs.SelectedIndex = trail.Count - 1;
}
private List BuildBreadcrumbTrail(string pageId)
{
var trail = new List();
string currentPage = pageId;
while (currentPage != null)
{
trail.Insert(0, currentPage);
currentPage = pageHierarchy[currentPage].Parent;
}
return trail;
}
private void OnNavigationClicked(object sender, CrumbClickedEventArgs e)
{
var clickedPageId = e.ItemName;
// Navigate to clicked page
PageNavigationRequested?.Invoke(this, clickedPageId);
// Update breadcrumbs to show only up to clicked level
NavigateToPage(clickedPageId);
}
public class PageInfo
{
public string Title { get; set; }
public string Icon { get; set; }
public string Parent { get; set; }
}
}
// Usage in main form
var websiteNav = new WebsiteNavigationControl();
websiteNav.PageNavigationRequested += (sender, pageId) =>
{
LoadPage(pageId);
};
// Navigate to a deep page
websiteNav.NavigateToPage("gaming"); // Will show: Home ? Products ? Electronics ? Computers ? Laptops ? Gaming
Application Menu Breadcrumbs
public class ApplicationMenuBreadcrumbs : UserControl
{
private BeepBreadcrumps menuBreadcrumbs;
private Stack navigationStack;
public ApplicationMenuBreadcrumbs()
{
InitializeMenuBreadcrumbs();
navigationStack = new Stack();
}
private void InitializeMenuBreadcrumbs()
{
menuBreadcrumbs = new BeepBreadcrumps
{
Size = new Size(600, 38),
Location = new Point(0, 0),
Style = BreadcrumbStyle.Pill,
SeparatorText = "❯",
ItemSpacing = 12,
ShowIcons = false,
Dock = DockStyle.Fill
};
menuBreadcrumbs.CrumbClicked += OnMenuBreadcrumbClicked;
this.Controls.Add(menuBreadcrumbs);
// Start with main menu
NavigateToMenu("main", "Main Menu");
}
public void NavigateToMenu(string menuId, string menuTitle)
{
// Add to navigation stack
navigationStack.Push(new MenuLevel { Id = menuId, Title = menuTitle });
// Update breadcrumbs
UpdateBreadcrumbsFromStack();
}
public void NavigateBack()
{
if (navigationStack.Count > 1)
{
navigationStack.Pop();
UpdateBreadcrumbsFromStack();
}
}
private void UpdateBreadcrumbsFromStack()
{
menuBreadcrumbs.Clear();
foreach (var level in navigationStack.Reverse())
{
menuBreadcrumbs.AddItem(level.Id, level.Title);
}
// Set selection to current level
if (menuBreadcrumbs.Items.Count > 0)
{
menuBreadcrumbs.SelectedIndex = menuBreadcrumbs.Items.Count - 1;
}
}
private void OnMenuBreadcrumbClicked(object sender, CrumbClickedEventArgs e)
{
// Navigate back to clicked level
int targetLevel = e.Index + 1; // +1 because index is 0-based
// Remove levels above the clicked one
while (navigationStack.Count > targetLevel)
{
navigationStack.Pop();
}
UpdateBreadcrumbsFromStack();
// Trigger menu change event
OnMenuLevelChanged(navigationStack.Peek().Id);
}
public event EventHandler MenuLevelChanged;
protected virtual void OnMenuLevelChanged(string menuId)
{
MenuLevelChanged?.Invoke(this, menuId);
}
private class MenuLevel
{
public string Id { get; set; }
public string Title { get; set; }
}
}
// Usage in application
var appMenuBreadcrumbs = new ApplicationMenuBreadcrumbs();
// Handle menu level changes
appMenuBreadcrumbs.MenuLevelChanged += (sender, menuId) =>
{
ShowMenuLevel(menuId);
};
// Navigate through menu levels
appMenuBreadcrumbs.NavigateToMenu("settings", "Settings");
appMenuBreadcrumbs.NavigateToMenu("user-settings", "User Settings");
appMenuBreadcrumbs.NavigateToMenu("profile", "Profile Settings");
// User can click on any breadcrumb to go back to that level
Theming
BeepBreadcrumps provides comprehensive theming with automatic application of theme colors and fonts:
Theme Application
var breadcrumbs = new BeepBreadcrumps
{
Theme = "DarkTheme",
UseThemeFont = true,
IsRounded = true,
ShowShadow = true
};
// Apply theme manually if needed
breadcrumbs.ApplyTheme();
// Theme automatically applies:
// - PanelBackColor: Main breadcrumb background
// - LabelForeColor: Default item text color
// - LinkColor: Clickable item text color
// - ButtonHoverBackColor: Hover background color
// - ButtonHoverBorderColor: Hover border color
Style-Specific Theming
- Classic Style - Uses border effects on hover with rectangular highlights
- Modern Style - Rounded hover effects with subtle elevation
- Pill Style - Rounded pill-shaped items with filled current item
- Flat Style - Underline hover effects with minimal visual styling
Best Practices
🧭 Navigation Design
- Clear hierarchy: Ensure breadcrumb levels represent logical navigation hierarchy
- Meaningful labels: Use descriptive, concise text for each breadcrumb item
- Consistent separators: Choose appropriate separators for your context (>, /, ❯, ‣)
- Current indication: Make the current page/location visually distinct
🎨 Visual Design
- Style consistency: Choose one breadcrumb style and use it consistently
- Appropriate sizing: Use adequate spacing and font sizes for readability
- Icon usage: Use icons sparingly and consistently when ShowIcons is enabled
- Color contrast: Ensure good contrast between text and background colors
⚡ Performance
- Efficient updates: Use AddItem/RemoveItem methods for single changes
- Batch operations: Clear and rebuild for multiple simultaneous changes
- Navigation optimization: Use NavigateToIndex for efficient backward navigation
- Memory management: Dispose of breadcrumb instances when no longer needed
♿ Accessibility
- Keyboard navigation: Ensure breadcrumbs work with keyboard navigation
- Screen readers: Provide meaningful text for assistive technologies
- Focus indicators: Ensure clear focus indicators for keyboard users
- Alternative text: Provide alt text or descriptions for icon-only items
Use the NavigateToIndex method when users click on breadcrumb items to automatically remove all items after the clicked level, providing intuitive backward navigation.
BeepBreadcrumps provides multiple visual styles and comprehensive hit testing, making it perfect for any hierarchical navigation scenario.
Avoid creating too many breadcrumb levels (more than 6-7) as this can overwhelm users and cause layout issues on smaller screens.