Do you Double-click on Combo Boxes?

AID: 3232
  • Status: Published

12400 points

  • Byharfang
  • TypeTips/Tricks
  • Posted on2010-06-10 at 11:28:32
Awards
  • Community Pick
  • Experts Exchange Approved
  • Editor's Choice
I do… Ever since I discovered the short-cut in Access 2.0, notably in the property sheets, I double click on all sorts of combo boxes — or their labels — to select the next item in the list.

This was a smart interface choice by the Access development team: you almost never need to double-click on a word in a combo box to select it, for example, and the feature is especially useful for combo boxes with short lists: “Yes/no”, “not indexed / indexed (with duplicates) / indexed (without duplicates)”, etc. It speeds up design and avoids having to create check boxes for properties that are really just flags.

To implement the same feature in your own applications, one line of code is enough (or three here, for readability).
Private Sub MyCombo_DblClick(Cancel As Integer)
    With MyCombo
        .Value = .ItemData((.ListIndex + 1) Mod .ListCount)
    End With
End Sub
                                    
1:
2:
3:
4:
5:

Select allOpen in new window


This sets the combo to the next item (list index plus one), wrapping to zero after the last item (modulo list count). The event can also be cancelled, but that is rarely useful.

It's not much code, but I use it so often that I normally create this function in the module dealing with the user interface:
Function ComboNextItem(cbo As ComboBox, Optional OrNull As Boolean)
' Selects the next item in the passed combo box.
' Set 'OrNull' to True (or 1) to select Null after the last item.

    If OrNull Then
        ' let Null happen by overflow of list index
        With cbo
            .Value = .ItemData(.ListIndex + 1)
        End With
    Else
        ' wrap list index to list count
        With cbo
            .Value = .ItemData((.ListIndex + 1) Mod .ListCount)
        End With
    End If
    
End Function
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:

Select allOpen in new window


Each combo box in my application then gets the following “On Dbl Click” property:

    = ComboNextItem(MyCombo)

or, in the rare cases where Null makes sense,

    = ComboNextItem(MyCombo,1)

This reduces the clutter in the form modules: no need for highly redundant event handlers for each and every combo on the form.


I hope you will find this trick useful!

Markus G Fischer
(°v°)

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
This article is part of the EE-book unrestricted Access.
Asked On
2010-06-10 at 11:28:32ID3232
Tags

Access

,

Access forms

,

combo box

,

double-click

Topic

Access Forms

Views
2064

Comments

Author Comment

by: harfang on 2010-06-16 at 16:56:11ID: 15843

I just had a chat about one-liners (it's a hobby). As I did announce one in the article but didn't deliver, I might as well show it here, complete with the option flag...

(^v°)
Function ComboNextItem(cbo As ComboBox, Optional OrNull As Boolean)
With cbo: .Value = .ItemData((.ListIndex + 1) Mod (.ListCount - OrNull)): End With
End Function

                                        
1:
2:
3:

Select allOpen in new window

Expert Comment

by: DatabaseMX on 2011-05-31 at 23:24:50ID: 27876

"you almost never need to double-click on a word in a combo box to select it"
Well, that may be, but ... that is ... standard Windows operation ... double click in a 'text' box to highlight and select, and I have found that users 'expect' that to happen.

So, I recommend that you incorporate Shift (or Control) + DoubleClick to Increment ... AND maybe ... Alt + DoubleClick to Decrement ... which would be handy if the list has more than a few items, say 10 or more ...  and you happen to go one past the intended selection. Just Alt+Double Click to backup one.

mx

Author Comment

by: harfang on 2011-06-01 at 01:14:51ID: 27878

To incorporate the keyboard shift state isn't entirely trivial. You can't just trap the keyboard events for the control because the user might press Shift in another control and then double-click on your combo's label. A WinAPI call (GetKeyState) would do the trick, though.

Another idea would be to restrict the feature to the label of the combo box. This requires to examine the mouse position, exposed in the low-level mouse events. If you need to trap two events, it's probably best to do so via a class module, much heavier than a simple function call.

Anyway, I just took the habit to double-click, most of the time on the label. If the combo box displays a long text, long enough that a user might want to copy-paste portions of it elsewhere, then the double-click should not be activated, I suppose. Have you ever encountered a situation like this?

(°v°)

Expert Comment

by: DatabaseMX on 2011-06-01 at 09:36:25ID: 27900

"I suppose. Have you ever encountered a situation like this?"
Well, not specifically.  Usually ... it would be a Text box.  But I was mainly ... just saying ....

"A WinAPI call (GetKeyState) would do the trick, though."
That's what I used for years.  I have that function in my mda library. Pretty simple really.

'Return the state of keyboard key requested....
Declare Function adiSWA_GetKeyState Lib "user32.dll" Alias "GetKeyState" (ByVal nKey%) As Integer

Public Function SWA_GetKeyState(argKeyName)
'Actions:Determine via Windows API call if specified key was depressed.
'             The argKeyName passed must be one on the Global keycode Constants
'------------------------------------------------------------------------------------------
    If adiSWA_GetKeyState(argKeyName) < 0 Then
        SWA_GetKeyState = True
    Else
        SWA_GetKeyState = False
    End If
End Function

Example usage:
If SWA_GetKeyState(vbKeyShift) = True Then    ' whatever

So, the GetKeyState could also be in the module that contains your ComboNextItem() function ... all self contained.

mx

Author Comment

by: harfang on 2011-06-01 at 16:27:19ID: 27909

Thank you MX

Your comments are a good addition to the article. This makes is simple to hook the “select next item” function to Ctrl+double-click (or Alt+click for that matter) and also a “select previous item” function to another combination, as you suggested.

Select previous, change line 8:
            .Value = .ItemData(.ListIndex - 1)
                                        
1:

Select allOpen in new window


and line 13:
            .Value = .ItemData((.ListCount + .ListIndex - 1) Mod .ListCount)
                                        
1:

Select allOpen in new window


This is with wrapping, which somehow seems less intuitive in this case, but would still be correct for simple Yes/No combos or similar.

(°v°)

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top Access Forms Experts

  1. LSMConsulting

    8,400

    0 points yesterday

    Profile
    Rank: Savant
  2. DatabaseMX

    8,064

    0 points yesterday

    Profile
    Rank: Savant
  3. capricorn1

    5,300

    0 points yesterday

    Profile
    Rank: Savant
  4. peter57r

    4,800

    0 points yesterday

    Profile
    Rank: Savant
  5. mbizup

    4,664

    0 points yesterday

    Profile
    Rank: Genius
  6. Helen_Feddema

    4,300

    0 points yesterday

    Profile
    Rank: Genius
  7. eghtebas

    4,132

    0 points yesterday

    Profile
    Rank: Genius
  8. boag2000

    2,940

    0 points yesterday

    Profile
    Rank: Genius
  9. _agx_

    2,800

    0 points yesterday

    Profile
    Rank: Genius
  10. Bitsqueezer

    2,800

    0 points yesterday

    Profile
    Rank: Wizard
  11. bingie

    2,000

    0 points yesterday

    Profile
    Rank: Guru
  12. dqmq

    2,000

    0 points yesterday

    Profile
    Rank: Genius
  13. imnorie

    2,000

    0 points yesterday

    Profile
    Rank: Genius
  14. als315

    2,000

    0 points yesterday

    Profile
    Rank: Genius
  15. harfang

    1,680

    20 points yesterday

    Profile
    Rank: Genius
  16. hnasr

    1,500

    0 points yesterday

    Profile
    Rank: Genius
  17. etsherman

    1,500

    0 points yesterday

    Profile
    Rank: Sage
  18. jrogersok

    1,200

    0 points yesterday

    Profile
  19. ABeasley

    1,200

    0 points yesterday

    Profile
  20. eoinisme

    1,000

    0 points yesterday

    Profile
  21. sparab

    752

    0 points yesterday

    Profile
    Rank: Guru
  22. LPurvis

    720

    0 points yesterday

    Profile
    Rank: Genius
  23. khairil

    668

    0 points yesterday

    Profile
    Rank: Wizard
  24. Nick67

    668

    0 points yesterday

    Profile
    Rank: Sage
  25. sb9

    500

    0 points yesterday

    Profile
    Rank: Wizard

Hall Of Fame