Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Create a Breadcrumb Menu in VB.NET WinForms

0.00/5 (No votes)
21 Feb 2007 2  
Provide a dynamic menu for drilling through data, or using the new Vista style of breadcrumbing for menu control.

Screenshot - breadcrumb.gif

Introduction

Dynamic menu creation is nothing out of the ordinary. Developers can limit menu options based on user authorization. They (we) can also add menu items if a situation demands it, such as a form field meeting a certain value.

Menus traditionally come in two flavors on Windows Forms: text and buttons. Text links are items such as File->Save As. Buttons are, well, buttons.

Web pages can use a third type of menu known as a breadcrumb menu. It's a great way to see where you are and how you got there. For example:

Home > Forums > .NET > VB.NET > General

I had a recent situation where a user wanted to drill-down (data mine) via listviews / datagrids to deeper content. They needed to know where they were - like the big map at the shopping mall that says "you are here". Breadcrumbs!

I knew that my breadcrumb menu would need three key pieces of functionality:

  1. Add a menu breadcrumb at each drill down.
  2. Give user the ability to back up in the data via the breadcrumb menu.
  3. Remove a menu option if the user did the above.

Details

The first part of the breadcrumb solution was to build a user control. I would need three of these on the form so a user control would fit nicely - OK, and I could reuse it later.

  • Build Functionality: Each time a menu item is added, it would add a symbol and the menu item, such as > Menu1. The LinkLabel would be used for the menu items.
  • Remove Functionality: If a user clicks on any link other than the last link in the breadcrumb chain, all the subsequent breadcrumbs should be removed.
  • Click Functionality: When the user clicks a LinkLabel, the form that holds the user control should receive the click event and process the correct breadcrumb click.

Problem Areas

It's easy to add a control at runtime. The problem is knowing where to add the control. For this reason, the user control will contain a private variable that contains the current width of all controls. Using this method, each subsequent control will be added in the right location.

The symbol > in the breadcrumb menu will be a label. This label will be given an identifier for easy reference for removal. Same goes for the LinkLabels. Each will be marked with a Tag of the same number to identify the breadcrumb set. This is important for removing breadcrumb items.

Pre-coding

Create a new Windows Application project. Add a user control. Name it ClsBreadCrumb. Size the user control to 480x16. The control will be tall enough to hold a LinkLabel and wide enough to be placed on a form. The control can be resized on the hosted form at a later time, if necessary.

Coding

User Control

Define the private variables:

'used to item group count
Private iItemCount As Integer
'used for proper label placement
Private iIncreasingLength As Integer

The Build Function. This function will be called each time a new menu item is added:

Public Function AddBreadCrumbLink(ByVal strNewLinkLabel As String)
    iItemCount = iItemCount + 1
    'add the > symbol
    Dim ctrlLK As New Label
    ctrlLK.Top = 0
    ctrlLK.Left = iIncreasingLength
    'create unique name
    ctrlLK.Name = "BC" & iItemCount
    ctrlLK.Text = ">"
    'the tag will be used to identify what 
    'symbol to delete and what was clicked
    ctrlLK.Tag = iItemCount 'strArrayList.Count - 1
    'important!  autosize the control so everything has a smooth look
    ctrlLK.AutoSize = True
    'now add the control to your form
    Me.Controls.Add(ctrlLK)
    'increase the private var so you will know where to 
    'start your next control
    iIncreasingLength = iIncreasingLength + ctrlLK.Width
    'add the new linklabel
    Dim ctrlLL As New LinkLabel
    ctrlLL.Top = 0
    ctrlLL.Name = strNewLinkLabel
    ctrlLL.Left = iIncreasingLength
    ctrlLL.Text = strNewLinkLabel
    'the tag will be used to identify what 
    'linklabel to delete and what was clicked
    ctrlLL.Tag = iItemCount
    ctrlLL.AutoSize = True
    iIncreasingLength = iIncreasingLength + ctrlLL.Width
    Me.Controls.Add(ctrlLL)
    'add a handler for the linklabel
    'same userd for all and we will use the control.tag property
    ' to see which was clicked
    AddHandler ctrlLL.Click, AddressOf myLinkLabel_Click

End Function

Private Sub myLinkLabel_Click(ByVal sender As Object,  _
    ByVal e As System.EventArgs)
    'event is raised to the form that holds this control
    RaiseEvent ItemClicked(Me, New ItemClickedEventArgs(sender.name))
    'we are moving back in the menu so we need to adjust our menu.
    RemoveLaterMenuItems(sender.tag)
End Sub

Time to remove those menu items:

Private Sub RemoveLaterMenuItems(ByVal strTagIdentifierForMenuDeletion As String)

    Dim intValFromMenu As Integer
    Dim iMax As Integer
    Dim iFor As Integer
    Dim iCount As Integer

    intValFromMenu = CInt(strTagIdentifierForMenuDeletion)

    Do Until ClearMenuItems(intValFromMenu) = True
        'each breadcrumb is made up of a label and a linklabel.
        'each is tagged with the same number
        'each time a set is deleted, we decrease the itemcount by 1
        iCount = iCount + 1
        If (iCount Mod 2 = 0) Then
            iItemCount = iItemCount - 1
        End If
    Loop

End Sub

Private Function ClearMenuItems(ByVal intValFromMenu As Integer) _
    As Boolean
    Dim intValFromControl As Integer

    ClearMenuItems = False
    Dim ThisCtrl As Control
    For Each ThisCtrl In Me.Controls
        'identify labels and link labels for that 
        'tag set (1's, 2's, etc.)
        intValFromControl = CInt(ThisCtrl.Tag)
        If intValFromControl > intValFromMenu Then
            iIncreasingLength = iIncreasingLength - ThisCtrl.Width
            Me.Controls.Remove(ThisCtrl)
            Exit Function
        End If
    Next
    ClearMenuItems = True
End Function

Dealing with the Raise Events:

Public Event ItemClicked(ByVal sender As Object, ByVal e As ItemClickedEventArgs)

Public Class ItemClickedEventArgs
    Inherits System.EventArgs
    Public ItemText As String
    Public Sub New(ByVal Text As String)
        Me.ItemText = Text
    End Sub
End Class

Open up the form and build the project. In the toolbar, select "My User Controls" and drag the control to your Form1 form.

Let's add a bit of color to the user control:

Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs)  Handles MyBase.Load
    ClsBreadCrumb1.BackColor = Color.PaleGoldenrod
End Sub

Add a Button labeled cmdAddMenuItem and paste the following code:

Private Sub cmdAddMenuItem_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles cmdAddMenuItem.Click
    ClsBreadCrumb1.AddBreadCrumbLink("LinkLabel" & icount)
    icount = icount + 1
End Sub

The icount counter is only used to provide different menu item names.

Finally, we want to handle those click events so we know what LinkLabel the user clicked.

Private Sub ClsBreadCrumb1_ItemClicked(ByVal sender As Object, _
        ByVal e As clsBreadCrumb.ItemClickedEventArgs) _
        Handles ClsBreadCrumb1.ItemClicked
    MessageBox.Show(Me, "The item " & e.ItemText & " was clicked.")
End Sub

Conclusion

This is a very basic tutorial on creating a breadcrumb style menu. It could probably be modified for using control arrays in VB 2005. Microsoft Vista now uses the breadcrumb system in the Control Panel section, among others, so we might be using this style of menu in applications a year down the road.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here