Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Monday, December 20, 2021

Assigning Images To ListView Items Tutorial-03

The ImageList ActiveX Control.

For Assigning Images to the ListView control, we need the help of another ActiveX Control: the ImageList Control.  We have seen Icons in Windows Explorer view, Folder-like images in the folder-closed state, when you click on the folder it displays an open Folder image and different types of images based on the file type. We don't have that much flexibility here, but we can display Icon images in the ListView Control's ColumnHeaders, ListItems, and ListSubItems object members while populating their contents. 

The Sample Demo Images.

The sample image of NorthWind Trading Employees listing with their Photos (small images) in the ListView Control:

Larger image sizes will increase the row height of records, but the photos can be larger than this.

A sample Image of ListView Control is given below (in the right-side Panel) that we have used along with the TreeView Control. The TreeView ActiveX Control was introduced to you in an earlier Series of Tutorials on TreeView Control.  You can find the List of TreeView Control Tutorial Series links at the bottom of this page.

In the above picture, I have used Icon images in all data columns and on column header labels to demonstrate the possibility of image display on ListView Control. 

The folder close and open states are displayed in the left panel on TreeView Control Nodes and they work differently than on ListView Items. The folder-open image is displayed when the TreeView Node receives a Click. A second click on the same Node displays the folder-closed image.

The ListView Control Programming Tutorial Series.

Hope you have gone through the ListView Control's earlier Tutorial Sessions-1 and 2 and are ready to take up this new Episode on the usage of ImageList Control along with the ListView Control.  The earlier Tutorial links are given below to review and to get ready to continue with this Session. Some of the basics of ListView Control are already present and explained there with VBA Code and you will be in a better position to continue here and understand what is happening here.

  1. ListView Control Tutorial-01.

  2. ListView Control Tutorial-02.

Source Data and Demo Form.

Let us start with a new Form and the Employees Table for our new ListView Control Demo Project.  Import the Employees Table from the NorthWind.accdb sample Database.  

  1. Create a new SELECT Query with the SQL given below and save it with the name EmployeesQ.

    SELECT [TitleOfCourtesy] & " " & [FirstName] & " " & [LastName] AS [Employee Name], 
    Employees.EmployeeID, 
    Employees.Title, 
    Employees.HireDate, 
    Employees.Address, 
    Employees.City, 
    Employees.Region, 
    Employees.PostalCode, 
    Employees.Country, 
    Employees.HomePhone, 
    Employees.Extension, 
    Employees.Notes
    FROM Employees;
    
  2. If your Employees Table structure is different doesn't matter.  For the first Column value only, I have combined three column values together to form the [Employees Name] as the first Column. Other column name values you can take as you have them and in any order, all of them or less as you please.

  3. Create a new Form and open it in Design View.

  4. Insert a Microsoft ListView Control from the ActiveX Controls List.

  5. Insert a Microsoft ImageList Control also from the ActiveX Controls List.

  6. Resize the ListView control like the sample image on the Form given below.  Move the ImageList Control and place it at the top right corner of the ListView control as shown in the image. You can place it anywhere in a convenient location on the Form.  It will not appear on the Form when the Form is in Normal view.

  7. Select the ListView Control and display the Property Sheet.

  8.  Change the Name Property Value to ListView1. 

  9. Select the ImageList Control, display its Property Sheet, and change the Name Property value to ImageList0.

  10. Note: Both the above controls have their own dedicated Property Sheets.  Their property names and values may appear in Access Property Sheet also.  If we make some changes in the Access Property Sheet then all of them may not update on the ListView and ImageList Controls. We have to make changes to the Control's own Property Sheet.

  11. ListView Control Property Sheet.

  12. Right-Click on the ListView Control, highlight the ListViewCtrl Object option in the displayed list, and select Properties.  The General Tab of the ListView Control Property Sheet will look like the Image given below.  

  13. Change the Property Values on the General Tab as shown in the Image above.

    First of all, we will load the Employees' data in the ListView Control.

    The Form Module VBA Code

  14. Copy and Paste the following VBA Code into the Form's Class Module:

    Option Compare Database
    Option Explicit
    
    Dim lvwList As MSComctlLib.ListView
    Dim lvwItem As MSComctlLib.ListItem
    Dim ObjImgList As MSComctlLib.ImageList
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    
    
    Private Sub cmdClose_Click()
       DoCmd.Close acForm, Me.Name
    End Sub
    
    Private Sub Form_Load()
     Call LoadListView("EmployeesQ")
    End Sub
    
    Private Sub LoadListView(ByVal tblName As String)
        Dim strFldName As String
        Dim intCounter As Integer
        Dim j As Integer
        Dim strLabel As String
    
    'Assign ListView Control on Form to lvwList Object
    Set lvwList = Me.ListView1.Object
    'Set ObjImgList = Me.ImageList0.Object
        
    'Assign Form Header labels Caption Text
     strLabel = UCase(tblName) & " " & "IN LISTVIEW CONTROL - TUTORIAL-03"
     Me.Label8.caption = strLabel
     Me.Label9.caption = strLabel
     
     With lvwList
        '.Icons = ObjImgList
        '.SmallIcons = ObjImgList
        '.ColumnHeaderIcons = ObjImgList
        .Font = "Verdana"
        .Font.Size = 10
        .Font.Bold = True
     End With
     
     Set db = CurrentDb
     Set rst = db.OpenRecordset(tblName, dbOpenSnapshot)
     
     'Create Column Headers for ListView
     With lvwList
        .ColumnHeaders.Clear 'initialize header area
        For j = 0 To rst.Fields.Count - 1
            strFldName = rst.Fields(j).Name
       'Syntax:
       '.ColumnHeaders.Add Index, Key, Text, Width, Alignment, Icon
            .ColumnHeaders.Add , , strFldName, iif(j=0,3200,2000)
        Next
     End With
     
     'Initialize ListView Control
      While lvwList.ListItems.Count > 0
            lvwList.ListItems.Remove (1)
      Wend
    
     With lvwList
     Do While Not rst.EOF And Not rst.BOF
    
       'Syntax  .ListItems.Add(Index, Key, Text, Icon, SmallIcon)
            Set lvwItem = .ListItems.Add(, , CStr(Nz(rst.Fields(0).Value, "")))
            
       'Add next columns of data as sub-items of ListItem
            With lvwItem
       'Syntax     .Add Index,Key,Text,Report Icon,TooltipText
             For j = 1 To rst.Fields.Count - 1
                .ListSubItems.Add , , CStr(Nz(rst.Fields(j).Value, ""))
             Next
    
           End With
           rst.MoveNext
    Loop
    rst.Close
        'reset lvwItem object
        Set lvwItem = Nothing
    End With
    
    Set rst = Nothing
    Set db = Nothing
    End Sub
    
    

    Note:  The Red-Colored VBA lines of ImageList control are Commented out from executing for the time being and we will enable them shortly.

  15. Save your Form with the Name frmEmployees.

  16. Open the Form in Normal View. 

    The EmployeesQ Query Records Listing will look like the following Image:

Review of the VBA Code

We have already gone through the above VBA Code in the earlier ListView Control Tutorial-01 and 02  Sessions, except for a few lines on ImageList Control declaration, initialization, and a few lines for the Font-Name, Font-Size, and Font-Style settings.  Another change we have made in the earlier VBA Code here is the LoadListView() program, it needs a Table/Query Name as a parameter.  All Query Types, except Action Queries, Access Tables, and Linked Table Names are Valid. The Table or Query name is passed when the program is called from the Form_Load() Event Procedure.

All the Table/Query Field Names are used as ColumnHeader Label Text (the third parameter) in the ColumnHeaders.Add() method. The first parameter Index and second parameter Key Values are not used. The Index sequence numbers will be inserted by the system automatically. 

The fourth parameter is the Column-Width value in pixels and we have arbitrarily assigned the first column width value of 3200 pixels and for all other columns 2000 pixels.  The first column displays the Employee Name and it needs more width to display it properly.

The Alignment and Icon parameter values for Column Headers we have not used here.  By default, the left Alignment is assumed. The available Alignment options are given below.

  • 0 - lvwColumnLeft
  • 1 - lvwColumnRight
  • 2 - lvwColumnCenter

You can view the above options on the Column Headers Tab on the ListView Control Property Sheet. To view the above options:

  • Click on the Insert Column Button, and enter some temporary column-name in the Text Box below.

  • Click on the Alignment Property and view the above Options.  

  • Click on the Remove Column Button to Delete the temporary column name. 

  • Note: If you would like to add Column Header Labels manually, rather than loading field names through VBA Code, you can type them one by one here. They will appear as Column Header Labels when you display data.

The sample view of the Icon Image on the left side of the Header Column Names can be seen in the right-side panel in the second demo image on the top of this page.

The Query EmployeesQ first Column (Employee Name) is taken as the ListItems.Text in its Add Method. In this method also we have omitted the Index and Key Parameter values. Index numbers will be added automatically by the system, as serial numbers.

From the second field onwards all column values are loaded through the ListSubItems.Add() method  of the ListView Control.

Note: All the values are added to the ListItems.Text and in ListSubItems.Text parameter as Text data type only, irrespective of its original data type in the source Table/Query.  In the Code, we are performing a validation check on Field Values, just in case any of them contains a Null Value, and converts it into the text value with the CStr() built-in function.

The ImageList control.

The ImageList Control initializing statements we have commented out in the Main Program are shown in red color in the Code segment given below. We will explain and enable them when we are ready with our preparations for Uploading Images into the ImageList Control.

'Assign ListView Control on Form to lvwList Object
Set lvwList = Me.ListView1.Object
'Set ObjImgList = Me.ImageList0.Object
    
'Assign Form Header labels Caption Text
 strLabel = UCase(tblName) & " " & "IN LISTVIEW CONTROL - TUTORIAL-03"
 Me.Label8.caption = strLabel
 Me.Label9.caption = strLabel
 
 With lvwList
    '.Icons = ObjImgList
    '.SmallIcons = ObjImgList
    '.ColumnHeaderIcons = ObjImgList
    .Font = "Verdana"
    .Font.Size = 10
    .Font.Bold = True
 End With
 

The first statement with the red color above initializes the ObjImgList Object with ImageList control ImageList0 on the Form frmEmployees. Before making changes to the Code let us see what options we have for uploading some images into the ImageList Control.

About Uploading Images.

The next step is to upload some sample images into the ImageList Control.  This can be done in one of two ways. 

Before attempting this step, please create or get at least two small images (any of the popular image types like jpg, jpeg, bmp, png, etc.), preferably bmp type. The Image size options available on the ImageList Control, on the General tab of the Property Sheet, are 16 x 16, 32 x 3248 x 48 pixels, or Custom size.  

Right-Click on the ImageList Control, highlight the option ImageListCtrl Object, and select Properties. Before selecting any image for uploading select one of the above image sizes on the General Tab.  

  • If you have big Images and want to retain the original Image-Size then select Custom Option. 
  • Selecting any of the other options will reduce the Image to the selected size. This may reduce the image quality. Using very large images may occupy more space on the ListView Control when displayed.  
  • Icon-type images will be ideal to use.  
  • Experiment with big, small, and very small images and with different options to get some experience with the correct Image/Option selection for your needs.

You can use one of two ways to upload the Images into ImageList Control:

1. Upload Images from disk through VBA Procedure.

The sample VBA Procedure will look like the Code Segment given below, taken from the  TreeView Control Tutorial:

  
  Set objImgList = Me.ImageList0.Object
  objImgList.ListImages.Clear
  
strFolder = "D:\Access\TreeView\"
With objImgList
    With .ListImages
         .Add Index:=1, Key:="FolderClose", Picture:=LoadPicture(strFolder & "folderclose2.bmp")
         .Add Index:=2, Key:="FolderOpen", Picture:=LoadPicture(strFolder & "folderopen2.bmp")
         .Add Index:=3, Key:="ArrowHead", Picture:=LoadPicture(strFolder & "arrowhead.bmp")
    End With
End With

With tvw 'TreeView Control
    .ImageList = objImgList 'assign imagelist Object to TreeView Imagelist Property
End With

The first statement initializes the objImgList Object with ImageList0 control on the Form.

The next statement ensures that the existing images in the image list control, if any, are cleared in preparation for uploading from the disk. For this approach to work every time, the images must be always available on the disk.

The objImgList.ListImages.Add() method is called to upload images from disk using the named parameters.  When parameter names are used in the Add() method the parameter values can be given in any order like the Index:=1 can be given at the end of the line or Key:="FolderClose" as the first item and so on. Without the parameter names the Add() method parameters order will be as follows:

         .Add 1, "FolderClose", LoadPicture(strFolder & "folderclose2.bmp")

To display the Image on our ListView control, we can either use the Image Index Number 1  or the Key value "FolderClose" Text as the Icon or SmallIcon parameter values in the ListItems.Add() method.

We used the above method in the TreeView Control Tutorial earlier.  You may visit that Page and download the Demo Database.

This method loads the Images into the ImageList Object Instance in memory and the physical object on the form is not changed.  The Source Images on the Disk must be always available every time the frmEmployees is open.

2. Uploading Images from disk Manually.

This is a one-time exercise, finding the images on disk and uploading them into the ImageList Control.  

The main advantage is that once the images are uploaded into the ImageList Control they stay intact.  The ImageList control with Images can be copied-pasted for other Projects if the same images are required for more than one Project. Not necessary to load the images from Disk again. The ImgeList Control with Images can be shared with friends as well.

So, let us go for the best method of manual uploading of Images.  Create two .bmp images of 50 x 50 pixels resolution (image1.bmp, image2.bmp) and keep them ready in your folder, say D:\Access\ for reference.

  1. Open frmEmployees in design view.

  2. Right-Click on the ImageList Control, highlight ImageListCtrl Object option and select Properties.

  3. On the General tab, select the Custom Option to upload images with the original resolution.

    The General tab view of ImageList Control.

    The Images tab View of the ImageList Control

    Note: After trying out the uploaded images on the ListView control if you would like to try out other options 48 x 48, 32 x 32, 16 x 16 you must Remove all the uploaded images first then go to the General tab, select the required option and then upload the images again.  The selected images will be reduced to the selected image size.

    As you can see in the sample images tab I have uploaded two images by selecting Insert Picture Command Button and picking the images from my disk.  

    The first image is in the selected state and slightly in the raised position.  The Index control shows the value 1 and the Key textbox shows the text First. The Index value will appear automatically, but the Key value (any meaningful value that you can easily memorize and relate the image to the data) may enter manually.

We can use either the Index number or the Key text value in the Icon and in the SmallIcon Parameter of ListItems.Add() method.

Even if you plan to use the index number sequence, then the Image uploading sequence must Sync with the data you plan to upload in the ListView Control, like the Employee's Name should match with their photos in the correct sequence. 

A better method in Employees' cases is their First-name can be used as Key Text and very easy to relate to the record. Generalized images don't need to match with this kind of relationship checking, but their Key names will help to indicate what they do, like folder_closed or folder_opened.

  • Click on the Images tab.

  • Click on the Insert Picture and find your D:\Access\Image1.bmp image and select it, click the Open Button to upload the image into the ImageList Control.

  • Type any text value in the Key textbox (the Key Values must be unique).

  • Repeat steps 5 and 6 for the second image, and type the Key-value.

We are ready with our ImageList Control with sample images and ready to display them on the ListView Control.

Assigning ImageList Object to ListView Object Properties.

The following ListView Object Properties must be assigned to the ImageList Object in order to use the Image references on the ListView Control:

  1. ListView.ColumnHeaderIcons
  2. ListView.Icons
  3. ListView.SmallIcons

The next step is to assign the ImageList Object to the required ListView Object in VBA Code through the Object Properties: lvwList.ColumnHeaderIcons, lvwList.Icons, lvwList.smallIcons before we are able to use the image references (Index or Key values) in the ColumnHeaders.Add(), ListItems.Add(), and ListSubItems.Add() methods. We have already added the required VBA codes in the main program and kept them disabled.  All we have to do is to enable those lines of Code by removing the Comment symbol from them and adding the required image references in the above Add method's parameters.

  • Remove the comment symbols ( ' ) from all the four VBA Code lines shown above with red color in the LoadListView() Procedure. 
  • Modify the following statements, shown with red color in the main program LoadListView() as shown with Icon Index number 1 & 2 in the Icon and SmallIcon parameter positions respectively like in the Code segment with bold black letters given below:
     With lvwList
     Do While Not rst.EOF And Not rst.BOF
    
       'Syntax  .ListItems.Add(Index, Key, Text, Icon, SmallIcon)
           ' Set lvwItem = .ListItems.Add(, , CStr(Nz(rst.Fields(0).Value,"")))
           'Change to 
             Set lvwItem = .ListItems.Add(, , CStr(Nz(rst.Fields(0).Value,"")), 1, 2)
            
       'Add next columns of data as sub-items of ListItem
            With lvwItem
       'Syntax     .Add Index,Key,Text,Report Icon,TooltipText
             For j = 1 To rst.Fields.Count - 1
               ' .ListSubItems.Add , , CStr(Nz(rst.Fields(j).Value, ""))
               'Change to           
                 .ListSubItems.Add , , CStr(Nz(rst.Fields(j).Value, "")),,"Click"
             Next
    
           End With
           rst.MoveNext
    Loop
    rst.Close
  • Since you have only two images the First Image with index number 1 is used as the Icon Parameter and 2 is in the SmallIcon parameter position. The Icon Image is displayed only when you change the ListView display Option 0 - lvwIcon.  In the ListSubItems.Add() method we have not added an image reference and for the next parameter Tooltip text "Click" is added. The Click Text will display when the mouse pointer rests on any of the columns, from the second column onwards.

    After making the above changes in the VBA Code Save the Form frmEmployees with the changes.

    Open the Form in Normal View.  The view should look like the sample Image on the top of this page.

    The smallIcon will be visible in all other ListView Options. Check the sample ListView Images of Employee data given below.

    0 - lvwIcon View

    ListView Icon View

    2 - lvwList View

    The first Image on the top of this page is the 03 - lvwReport View. Only in this view, all column values are displayed in the DataSheet-like display.

    Change the Form in Design View.  Display the Property Sheet of the ListView Control. Change the View options and try out each view and find out what different views looks like.

    Download the Demo Database.

     

    1. Microsoft TreeView Control Tutorial
    2. Creating Access Menu with TreeView Control
    3. Assigning Images to TreeView Nodes
    4. Assigning Images to TreeView Nodes-2
    5. TreeView Control Checkmark Add Delete
    6. TreeView ImageCombo Drop-down Access
    7. Re-arrange TreeView Nodes By Drag and Drop
    8. ListView Control with MS-Access TreeView
    9. ListView Control Drag Drop Events
    10. TreeView Control With Sub-Forms

    3 comments:

    1. can I use imagelist and imagecombobox activex controls to show dropdown list with images

      ReplyDelete
    2. can I use imagelist with imagecombobox to show dropdown list with images

      ReplyDelete
    3. can I use imagelist and imagecombobox to show dropdown list with images

      ReplyDelete

    Comments subject to moderation before publishing.

    Powered by Blogger.