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
💡 Design Tip

Use the NavigateToIndex method when users click on breadcrumb items to automatically remove all items after the clicked level, providing intuitive backward navigation.

✅ Success Pattern

BeepBreadcrumps provides multiple visual styles and comprehensive hit testing, making it perfect for any hierarchical navigation scenario.

⚠️ Avoid Deep Hierarchies

Avoid creating too many breadcrumb levels (more than 6-7) as this can overwhelm users and cause layout issues on smaller screens.