Introduction.
In this session of the TreeView Control Tutorial, we will focus on programming the ImageComboBox Control. Our objective is to build an MS Access project drop-down menu using an ImageCombo control. Additionally, we will use a second ImageComboBox control to display the images along with their key values from the ImageList control. Both ImageComboBox controls will draw their images from a common ImageList control, into which the images were manually uploaded from the computer during an earlier session of this tutorial series.
The sessions of the TreeView Control Tutorial covered so far are as follows:
The TreeView Control Tutorial Session Links.
- Microsoft TreeView Control Tutorial
- Creating an Access Menu with a TreeView Control
- Assigning Images to TreeView Control
- Assigning Images to TreeView Control-2
- TreeView Control Check-Mark Add, Delete Nodes
The Demo View of Both ImageComboBoxes Expanded.
The completed MS-Access Project Drop-Down Menu Image is given below:
The Design View Image of the above Form is given below:
The Drop-Down ImageComboBox Source Data.
The source data for the new MS Access Project Drop-Down Menu is taken from our earlier Access Menu Project.
If you have not already done so, please download the demo database using the link provided in item 4 above. Once downloaded, you will have all the required data objects to proceed with this session.
The database includes three tables: Categories, Products, and Menu. It also contains two forms to display category and product data, along with a parameter form for filtering report data.
Additionally, we will utilize two forms—frmMenu and frmMenu2—which were introduced in our earlier tutorial sessions.
You will also find two reports for previewing the Categories and Products data items.
In addition, there are two macros designed to display simple messages. These macros can also be used to sequence action queries for data processing, particularly when working with more complex reports. In earlier tutorial sessions, we executed these actions by selecting options from the TreeView Control
Project Menu.
We will also need these objects here, as we are about to create a new drop-down menu using the ImageComboBox Control. The goal is to ensure that all objects can be opened through selections in the new drop-down menu, in the same way we accessed them earlier on the frmMenu2 form using the TreeView Control within this same database.
The Menu table image is given below for your reference.
Preparing for the Design of the Drop-Down Menu Form.
Open the Menu Form in Design View, and you will see two menu-related controls:
-
An ImageList control
-
An ImageComboBox control
Additionally, another ImageComboBox control has been placed on the right side of the form to display the images stored in the ImageList.
To set this up:
-
Copy the ImageList Control
-
Open the frmMenu2 form, copy the ImageList control, and paste it onto a new form named frmMenu3Combo.
-
This ImageList control already contains images that were manually uploaded from the computer in an earlier tutorial session.
-
Open the Property Sheet: right-click the ImageList control, select ImageListCtl Object, and then choose Properties to review the images and their key names.
-
-
Add the First ImageComboBox Control
-
From the ActiveX Controls group, insert a Microsoft ImageComboBox Control onto the left side of the form.
-
Rename this control to imgCombo1. This will serve as the drop-down menu.
-
-
Add the Second ImageComboBox Control
-
Insert another ImageComboBox control on the right side of the form.
-
Rename this control to imgCombo2. This control displays the images and their key names from the ImageList0 control in a drop-down list.
-
-
Add a Label
-
Place a label above the second ImageComboBox control.
-
Set its caption to Image List.
-
The Images Listed in the Image Combo Box control.
We will begin with the second control, imgCombo2, which is used to display the list of images from the ImageList control. Once you understand this code, creating the drop-down menu will become much easier.
The VBA code for the frmMenu3Combo form module has been divided into two parts. Let us start with the first part and examine its contents.
In the global declaration area, the main object variables are defined. The Form_Load() event procedure initializes the ImageList control on the form and assigns it to the object variable 'objImgList'. It then calls the cboImageList() subroutine, which loads the images from the ImageList control into the second ImageComboBox control (imgCombo2).
Now, let’s take a closer look at the code.
The first-part vba code, with the Form_Load() and cboImageList() subroutines listed below:
Dim imgcombo1 As MSComctlLib.ImageCombo Dim imgCombo2 As MSComctlLib.ImageCombo Dim objimgList As MSComctlLib.ImageList Const KeyPrfx As String = "X" Private Sub Form_Load() Set objimgList = Me.ImageList0.Object cboImageList 'load imagelist-combo 'CreateMenu 'Create Drop-Down Menu End Sub Private Sub cboImageList() Dim j As Integer Dim strText As String Set imgCombo2 = Me.ImageCombo2.Object imgCombo2.ImageList = objimgList For j = 1 To objimgList.ListImages.Count strText = objimgList.ListImages(j).Key imgCombo2.ComboItems.Add , , strText,j,,j Next imgCombo2.ComboItems(1).Selected = True End Sub
VBA Code Review.
In the global declaration area, we have defined the following variables:
-
imgCombo1 – the ImageComboBox control used for the project menu.
-
imgCombo2 – the ImageComboBox control used for displaying images from the ImageList control.
-
objImgList – an object variable representing the ImageList control on the form.
-
KeyPrfx – a constant variable assigned the character "X".
Within the Form_Load() event procedure, the objImgList variable is initialized with the ImageList control on the form using the following statement:
This allows all pre-loaded images in the ImageList control to be accessed through the objImgList object.
Next, the procedure calls the cboImageList() subroutine, which adds all the images to the imgCombo1 control.
For now, the call to the CreateMenu() subroutine has been commented out.
Inside the cboImageList() subroutine, two variables are declared.
Next, the following statement assigns the second ImageComboBox control on the form to the object variable imgCombo2:
Similar to the TreeView control, the imgCombo2 control includes an ImageList property, which is used to link it with the ImageList control. This allows the ImageComboBox to access the properties of the ImageList. The statement below establishes that link:
After this, a 'For…Next loop' is executed to iterate through the collection of images contained in the ImageList control. Each image is then processed and added to the imgCombo2 drop-down list.
The first item from the ImageList has its key value ("form_close"
) stored in the variable strText. In this example, we are using the Key value of the ImageList item as the text (or description) for the corresponding image in the ImageComboBox control.
Since no descriptive text is available apart from the key, it serves as the most suitable option. The Tag property, on the other hand, is left empty because it is for a different purpose later when working with the drop-down menu.
The next statement is an important one that we need to examine closely: the Add method of the ImageComboBox control. This method is used to add items (with images) to the ImageComboBox list.
The general syntax of the statement is as follows:
imgCombo2.ComboItems.Add [Index],[Key],[Text],[Image],[SelImage],[Indentation]
All the parameters of the Add() method are optional. For our initial test run of this control, we will supply values only for the [Text], [Image], and [Indentation] parameters.
After previewing the result of this first test run (the image list view), we will discontinue using the [Indentation] parameter for this ImageCombo control, since it is not required for our intended design.
Note: Keep in mind that we will later need the Indentation property when creating the drop-down menu. This will allow the menu items to visually resemble Root Nodes and Child Nodes, just as they appear in the TreeView control.
At that stage, we will also make use of the [Key] parameter—assigning it the same value as the Text parameter—so that we can reliably access a specific menu item’s Tag property value.
Image List with incrementing Indentation Param Setting.
The result of the first test run, displaying the image list in imgCombo2, appears as shown in the illustration below. This output is achieved by applying incremental values to the Indentation property for each item.
From this trial run, the effect of indentation is clearly visible: each successive item is shifted slightly to the right, one step further than the previous one. This feature is useful for positioning our project menu items so that they visually resemble Root-Level and Child Nodes, similar to the structure in the TreeView control.
After the strText value ("form_close"),
The first variable j refers to the ImageList’s index number. The [SelImage] parameter is skipped in our test, and the next occurrence of j is used to set the Indentation level for each list item when displayed in the ComboBox.
For the initial test run, after reviewing the output, you may remove all parameters that come after the image index value, as they are not required for our purpose.
The next statement is:
This selects the first item in the ComboBox. When the Combobox item is selected programmatically (through code), the Change() event of the ImageCombo control is triggered. However, when an item is selected manually on the form, this event is not fired. To address this, the Update() event is used; it ignores manual updates and instead attempts to invoke the event explicitly through code.
Save the form frmMenu3Combo and open it in Normal View. Expand the second ImageList ComboBox control and view the result. Remove the commas and the variable < j > at the end, after the first variable < j >, retained for the ImageList index number.
The VBA Code of the Project Drop-Down Menu.
Now, let us move on to the second part of the form module VBA code, where we will learn how to create the Access Drop-Down Menu. In this section, we will also see how to open Forms, Reports, and Macros by selecting an item from the ComboBox control.
The second part of the VBA code consists of two main procedures:
-
CreateMenu() – a subroutine that builds the project drop-down menu by adding menu items to the ImageComboBox control.
-
ImageCombo1_Click() – the event procedure that responds when a user selects a menu option, triggering the opening of the corresponding Access object.
The code for these procedures is shown below:
Private Sub CreateMenu() Dim db As DAO.Database Dim rst As DAO.Recordset Dim strSQL As String Dim strKey As String Dim strText As String Dim typ As Integer Set imgcombo1 = Me.ImageCombo1.Object imgcombo1.ImageList = objimgList strSQL = "SELECT ID, Desc, PID, Type,Macro,Form,Report FROM Menu;" Set db = CurrentDb Set rst = db.OpenRecordset(strSQL, dbOpenDynaset) Do While Not rst.EOF And Not rst.BOF If Len(Trim(Nz(rst!PID, ""))) = 0 Then strKey = KeyPrfx & CStr(rst!ID) strText = rst!Desc imgcombo1.ComboItems.Add , strKey, strText, 1, 2, 1 ' image index 1,2([image],[selectedimage]) 'imgcombo1.ComboItems.Add , strKey, strText, "folder_close", "folder_open", 1 Else strKey = KeyPrfx & CStr(rst!ID) strText = rst!Desc imgcombo1.ComboItems.Add , strKey, strText, 4, 5, 4 'last param is spacing 'imgcombo1.ComboItems.Add , strKey, strText, "left_arrow", "right_arrow", 4 'Check for the presense of Type Code If Nz(rst!Type, 0) > 0 Then typ = rst!Type With imgcombo1.ComboItems Select Case typ 'save type Code & Form/Report/Macro Name in Tag Property Case 1 .Item(strKey).Tag = typ & rst!Form Case 2 .Item(strKey).Tag = typ & rst!Report Case 3 .Item(strKey).Tag = typ & rst!Macro End Select End With End If End If rst.MoveNext Loop rst.Close imgcombo1.ComboItems.Item(1).Selected = True End Sub Private Sub ImageCombo1_Click() Dim strObject As String Dim strTag As String Dim typ As Integer strTag = ImageCombo1.SelectedItem.Tag typ = Val(strTag) strObject = Mid(strTag, 2) Select Case typ Case 1 DoCmd.OpenForm strObject, acNormal Case 2 DoCmd.OpenReport strObject, acViewPreview Case 3 DoCmd.RunMacro strObject End Select End Sub
Before diving into the VBA code, take a moment to review the Table Image (the third image from the top of this page), especially if you have not already done so in the earlier session on Access Project Menu creation.
The table fields are defined as follows:
-
ID – An AutoNumber field that provides a unique identifier for each record.
-
Desc – Contains either the object type group names (Forms, Reports, Macros) or the actual object names of forms, reports, and macros.
-
PID (Parent ID) – Empty for the object group names (Forms, Reports, Macros). These empty PID values ensure that the group names appear at the leftmost position in the ImageComboBox drop-down menu, with one-character space indentation. All other items (child objects) are indented by four character spaces.
This indentation technique makes the menu items visually resemble Root-Level and Child-Level Nodes, similar to the structure in a TreeView control—except that the connecting tree lines will not be displayed.
In the ImageComboBox control, the selected item’s image is positioned at the leftmost side. The Group items (such as Forms, Reports, Macros) appear with a one-character indentation, while the child items under each group are indented by four character spaces.
The PID field plays an important role in this arrangement.
-
If the PID field value is empty, the record is treated as a Group Name (e.g., Forms, Reports, Macros).
-
If the PID field contains a value, the record is treated as an Access Object Name, which must be opened when the user clicks it. These items are displayed as child members of their respective groups.
Although the actual key values in the PID field are not significant in this context, we need the field to determine the hierarchy. Alternatively, the Type field can also serve this purpose.
The Type field contains the object type codes:
-
1 – Form
-
2 – Report
-
3 – Macro
Based on this code, the next three fields—Form, Report, and Macro—store the actual object names. For clarity in design, these names have been kept in separate fields, though they could also be stored in a single column.
The Type Code and Object Name pair (say 2rptCategories) will be saved in the ImageComboBox’s Tag Property.
The CreateMenu() Subroutine.
Now, let’s move on to the VBA code of the CreateMenu() subroutine.
At the start of the procedure, the Database and other working variables are declared.
-
The imgCombo1 object variable is initialized with the Me.ImageCombo1 control on the form.
-
The 'imgCombo1.ImageList' property is then assigned the reference of the objImgList object, enabling direct access to the ImageList’s Index numbers and Key values.
-
The Menu table is opened as a recordset using an SQL string.
-
For each record, the PID field is checked:
-
If PID is empty, the record is treated as an object group name (e.g., Forms, Reports, Macros).
-
In this case, the ID value is prefixed with the constant "X" and stored in the variable strKey, while the Desc field value is stored in strText.
-
-
The Add() method of the ImageComboBox control is then called, and the first item is added to the drop-down menu.
imgcombo1.ComboItems.Add , strKey, strText, 1, 2, 1
The first parameter (Index) is omitted—Access assigns it automatically.
-
Key:
strKey
contains the ID value prefixed with the constant X (e.g.,X1
). -
Text:
strText
holds the Desc field value. -
Image / SelImage:
1
is the index (or"folder_close"
key) of the first ImageList image;2
is the index (or"folder_open"
key) of the second image. -
Indentation:
1
Indents the item one level.
Example:
Note: To confirm image index order, refer to the ImageCombo2 display you created earlier. If you like, you can also prepend the image index to the Text (not the Key) for clarity—for example: "1 form_close"
, "2 form_open"
.
@@@If the PID field value is non-zero, then the record represents an actual menu option (not a group header). In this case, the item is added under the Else clause.
The process is similar to how we added the group items earlier, but with a few differences:
-
For the [Image] and [SelImage] parameters, we use the ImageList item index values 4 and 5.
-
The Indentation parameter is set to 4 character spaces, so that these items appear as child members under their respective group headings.
Example:
This ensures that the group names (e.g., Forms, Reports, Macros) stay at the root level, while their associated objects are properly indented beneath them, visually simulating a TreeView hierarchy in the ImageComboBox.
Within the ImageCombo item’s Add() method, under the Else clause, we also need to store the Access Object Name along with its Type Code in the item’s Tag property.
For example:
Here:
-
"frmData Entry"
is the object name (in this case, a form). -
1
is the Type Code, which identifies it as a form (2 = report, 3 = macro).
When the user selects this item from the drop-down menu, the Click() event of the ImageComboBox fires. In this event procedure:
-
The Tag property value of the selected item is retrieved.
-
The value is split into the object name and the Type Code.
-
The Type Code is checked:
-
If it equals 1, the item is a form, and the form name is opened using:
-
This same logic will later be extended for Reports and Macros, using their respective Type Codes.
@@@With this, all the records from the Menu Table are successfully added to the ImageComboBox control.
The statement:
sets the first item as the default selection in the ImageComboBox. When this line of code executes, the Change() event is triggered; however, selecting an item directly in Form View does not fire the Change event.
Note: Before running the form to test the drop-down menu, make sure to remove the comment symbol from the CreateMenu
call in the Form_Load() event procedure. This line was commented out earlier during trial runs when we were testing image display in the ImageCombo2 control.
The ImageCombo1_Click() event fires whenever the user selects an item from the drop-down menu. In this procedure, the selected item’s Tag property is parsed to retrieve the Type Code and the Object Name, and the corresponding Access object is opened using:
Finally, for your reference and practice, the Demo Database (ProjectMenuV221.accdb) is provided in .zip format for download.