Can't deselect item in non-multi-select listbox? (1 Viewer)

AOB

Registered User.
Local time
Today, 16:35
Joined
Sep 26, 2012
Messages
615
I'm embarrassed to even ask this question but for some reason I can't figure it out...

Very, very simple problem - I have a ListBox that has Multi-Select set to None (i.e. only allow one item to be selected at any time)

When I select an item, I can't seem to deselect it again? I can only change which item is selected? Have tried holding Shift when clicking, the item will not deselect?

Am I missing something glaringly obvious? (Apologies, I haven't developed in Access in years and I just can't remember the vagaries of listboxes... :oops:)

Thanks!
 

moke123

AWF VIP
Local time
Today, 11:35
Joined
Jan 11, 2013
Messages
3,920
That's normal behavior.

What about adding a double click event to set the listbox =null?
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:35
Joined
May 21, 2018
Messages
8,529
I something add a Clear button next to the listbox. Same as the double click idea, but makes it obvious. If using the dblclick then add the label too. "Double click to Clear list"
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 10:35
Joined
Feb 28, 2001
Messages
27,187
The "ESC" key can act as a "spot UNDO" for controls. Have you tried that?
 

AOB

Registered User.
Local time
Today, 16:35
Joined
Sep 26, 2012
Messages
615
Thanks everybody. All coming back to me now... Why would that be normal behaviour by design I wonder? Surely there should be a native / intuitive method of undoing the selection rather than having to implement one via code?

For what it's worth, I've decided to go with this as it replicates the "deselect" behaviour of the multi-select version which users (myself included!) will probably try instinctively (I do appreciate that it doesn't check to confirm that the user is clicking on the actual selected item as opposed to some arbitrary other item but I don't think that's going to be too much of an issue...)

Code:
Private blnCtrlKeyPressed As Boolean

Private Sub lst_KeyDown(KeyCode As Integer, Shift As Integer)
    If (Shift And acCtrlMask) > 0 Then
        blnCtrlKeyPressed = True
    End If
End Sub

Private Sub lst_KeyUp(KeyCode As Integer, Shift As Integer)
    blnCtrlKeyPressed = False
End Sub

Private Sub lst_AfterUpdate()
    With Me
        If blnCtrlKeyPressed Then
            .lst.Value = ""
        End If
    
        If Len(.lst.Value) > 0 Then
           ...
        Else
           ...
        End If
    End With
End Sub
 

moke123

AWF VIP
Local time
Today, 11:35
Joined
Jan 11, 2013
Messages
3,920
Perhaps a custom class? Not extensively tested but appears to work well. Example attached.

In a class Module:
Code:
Option Compare Database
Option Explicit

Private WithEvents m_objlbx As Access.ListBox
Private m_oldVal As Variant
Private m_newVal As Variant

Sub initLBX(Lb As ListBox)

    Set m_objlbx = Lb

    m_oldVal = m_objlbx.Value

    m_objlbx.OnClick = "[Event Procedure]"

End Sub

Private Sub m_objlbx_Click()

    m_newVal = m_objlbx.Value
  
    If m_newVal = m_oldVal Then
  
        m_objlbx.Value = Null
      
        m_oldVal = Null
      
    Else
  
        m_oldVal = m_objlbx.Value
    
    End If

End Sub

Public Property Get oldVal() As Variant: oldVal = m_oldVal: End Property

Public Property Get newVal() As Variant: newVal = m_newVal: End Property

Public Property Let newVal(ByVal NewValue As Variant): m_newVal = NewValue: End Property

Public Property Let oldVal(ByVal NewValue As Variant): m_oldVal = NewValue: End Property

Public Property Get lbx() As Access.ListBox: Set lbx = m_objlbx: End Property

Public Property Set lbx(ByVal objNewValue As Access.ListBox): Set m_objlbx = objNewValue: End Property

Form Code:
Code:
Option Compare Database
Option Explicit

Dim clsLbx As clsSingLbx

Private Sub Form_Load()
Set clsLbx = New clsSingLbx
clsLbx.initLBX Me.List0

End Sub
 

Attachments

  • SingleSelectLBX.accdb
    468 KB · Views: 82
Last edited:

Pat Hartman

Super Moderator
Staff member
Local time
Today, 11:35
Joined
Feb 19, 2002
Messages
43,275
Why would that be normal behaviour by design I wonder? Surely there should be a native / intuitive method of undoing the selection rather than having to implement one via code?
There IS one. It is the esc key:) The same method works on all controls. There is no special method for listboxes.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:35
Joined
May 21, 2018
Messages
8,529
I tried the escape key. Didn't work for me.
Yeah, that will only work on a new record where it was previously null. If it has a previous value it only goes back to that. It undos not unselects.
 

moke123

AWF VIP
Local time
Today, 11:35
Joined
Jan 11, 2013
Messages
3,920
I've tested that class on bound, unbound, query based, and value list listboxes and it seems to work flawlessly so far.
I'm not quite sure if or where I might use it but I'll stick it in my Application Parts templates just in case.


DeSelect.gif
 
Last edited:

Pat Hartman

Super Moderator
Staff member
Local time
Today, 11:35
Joined
Feb 19, 2002
Messages
43,275
It works as I described on bound controls. For unbound controls there is no .OldValue property to revert to. It doesn't matter whether the record is new or existing. For existing records, if the value was null, it reverts to the null value which IS the .OldValue. If the .OldValue is not null, then esc reverts to whatever the .OldValue was which doesn't seem to be what the OP was asking for.

When I answered the question, it never occured to me that the OP wanted to remove a saved value and bring the list box back to null. I thought we were talking about new records or existing records where the saved value was null.

I suppose if you want to be able to revert to null, you can do one of three things.
1. Add a Null option to the RowSource for the listbox (this is the common solution)
2. Add a clear list selection button and use code to set it to null.
3. Use a combo instead of a listbox. It also takes up less room in addition to allowing the control to revert to null (assuming null is a valid value)

Not being able to revert to null affects two other controls as well. You don't "see" null for Y/N (black square instead of white or the check mark) unless you bind it to an integer instead of a Y/N data type.
1. Option Group
2. Y/N
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 23:35
Joined
May 7, 2009
Messages
19,245
you may try to Add a command button (cmdClearSelection) on your form
to "clear" the selection from the listbox.
add code to its Click Event to do the actual clearing:
Code:
Private Sub cmdClearSelection_Click()
    Dim i As Integer
    For i = 0 To Me.YourListboxName.ListCount - 1
        Me.YourListboxName.Selected(i) = False
    Next
End Sub

or
Code:
Private Sub cmdClearSelection_Click()
    Dim var
    For Each var In Me.YourListboxName.ItemsSelected
        Me.YourListboxName.Selected(var) = False
    Next
End Sub
 
Last edited:

moke123

AWF VIP
Local time
Today, 11:35
Joined
Jan 11, 2013
Messages
3,920
Not being able to revert to null affects two other controls as well.
In an option group you can deselect a selection in the double click event

Code:
Private Sub Frame3_DblClick(Cancel As Integer)

Me.Frame3 = Null

End Sub

With a check box there are 2 options.

Set the triple state setting to yes and it will cycle through Yes, No, Null

Or use the double click event

Code:
Private Sub Check12_DblClick(Cancel As Integer)
Me.Check12 = Null
End Sub
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 11:35
Joined
Feb 19, 2002
Messages
43,275
You can always solve the problem with code, just as we solved the list box problem with code.
 

AOB

Registered User.
Local time
Today, 16:35
Joined
Sep 26, 2012
Messages
615
This has escalated... :ROFLMAO:

I'm actually going to solve the problem by replacing the listbox with a subform that looks like a listbox (for a variety of reasons, but one of the upshots is that you can customise the select / deselect behaviour far more easily - that's not the primary reason for the switch though...)

Running into another problem but I'll start a new thread as it's technically a different problem to this one but I'll link to it here...
 
Last edited:

moke123

AWF VIP
Local time
Today, 11:35
Joined
Jan 11, 2013
Messages
3,920
but one of the upshots is that you can customise the select / deselect behaviour far more easily
I think I'd disagree with you on that, at least in the context of your original question.
I'll venture a guess that your not that familiar with custom classes. The beauty of them is that you write them once and can then use them in any project with very little code and no modifications.

With the example posted above, you need only to import the class module into your project. You do not need to make any changes or modifications to it. You don't even need to really understand it.

In your form containing the listbox, or listboxes, you only need 3 lines of simple code.

In the declarations section of your form you declare a module level variable for the class object - Dim clsLbx As clsSingLbx

In the OnLoad event of your form you instantiate an instance of the class - Set clsLbx = New clsSingLbx
and initialize it by passing your list box object to the class - clsLbx.initLBX Me.TheNameOfYourListbox

The only change is replacing Me.TheNameOfYourListbox with the name of your list box.

Doesn't get much easier than that.
 

AOB

Registered User.
Local time
Today, 16:35
Joined
Sep 26, 2012
Messages
615
No, agreed, and I do use custom classes elsewhere.

In this particular case though, the restrictions of using a listbox control make a subform a better alternative. What I'm trying to do is create a kind of template for manipulation of "static data" within the DB. So a basic form that can be replicated multiple times depending on which table / tables need to be manipulated.

With a listbox, you can only select an item. With a continuous subform, you can add command buttons to each record and fire functions specific to that record from within the subform. That is the true motivation for switching from a listbox to a subform. The added benefit with subforms just happens to be that I can simultaneously impose my own select / deselect behaviour far more easily than with a "stock" listbox. Yes, I can impose that same behaviour with a custom class - but I can't make a listbox host buttons!
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 11:35
Joined
Feb 19, 2002
Messages
43,275
In this particular case though, the restrictions of using a listbox control make a subform a better alternative.
Except that they can sort of look similar, they are different objects and used for different purposes for different kinds of data.

A single select listbox is a control that is bound to one column of one row. A subform is bound to a table/query of multiple columns and multiple rows. They are not interchangeable.
 

AOB

Registered User.
Local time
Today, 16:35
Joined
Sep 26, 2012
Messages
615
Except that they can sort of look similar, they are different objects and used for different purposes for different kinds of data.

A single select listbox is a control that is bound to one column of one row. A subform is bound to a table/query of multiple columns and multiple rows. They are not interchangeable.

Yup, totally accept that, and agree. What I'm saying is, there are situations where I want something bound to multiple rows and columns?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 11:35
Joined
Feb 19, 2002
Messages
43,275
Then you never had a single column to begin with. Have we moved on to a new problem since this is not the solution to the problem you came here with?
 

Users who are viewing this thread

Top Bottom