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:
- Add a menu breadcrumb at each drill down.
- Give user the ability to back up in the data via the breadcrumb menu.
- Remove a menu option if the user did the above.
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.
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.
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.
Define the private variables:
Private iItemCount As Integer
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
Dim ctrlLK As New Label
ctrlLK.Top = 0
ctrlLK.Left = iIncreasingLength
ctrlLK.Name = "BC" & iItemCount
ctrlLK.Text = ">"
ctrlLK.Tag = iItemCount
ctrlLK.AutoSize = True
iIncreasingLength = iIncreasingLength + ctrlLK.Width
Dim ctrlLL As New LinkLabel
ctrlLL.Top = 0
ctrlLL.Name = strNewLinkLabel
ctrlLL.Left = iIncreasingLength
ctrlLL.Text = strNewLinkLabel
ctrlLL.Tag = iItemCount
ctrlLL.AutoSize = True
iIncreasingLength = iIncreasingLength + ctrlLL.Width
AddHandler ctrlLL.Click, AddressOf myLinkLabel_Click
Private Sub myLinkLabel_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
RaiseEvent ItemClicked(Me, New ItemClickedEventArgs(sender.name))
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
iCount = iCount + 1
If (iCount Mod 2 = 0) Then
iItemCount = iItemCount - 1
Private Function ClearMenuItems(ByVal intValFromMenu As Integer) _
Dim intValFromControl As Integer
ClearMenuItems = False
Dim ThisCtrl As Control
For Each ThisCtrl In Me.Controls
intValFromControl = CInt(ThisCtrl.Tag)
If intValFromControl > intValFromMenu Then
iIncreasingLength = iIncreasingLength - ThisCtrl.Width
ClearMenuItems = True
Dealing with the Raise Events:
Public Event ItemClicked(ByVal sender As Object, ByVal e As ItemClickedEventArgs)
Public Class ItemClickedEventArgs
Public ItemText As String
Public Sub New(ByVal Text As String)
Me.ItemText = Text
Open up the form and build the project. In the toolbar, select "My User Controls" and drag the control to your
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
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
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) _
MessageBox.Show(Me, "The item " & e.ItemText & " was clicked.")
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.