The coolest UI I ever built involved displaying "paired" electrical connector part numbers. I have a list of Male connectors, and a second list of Female connectors. I wanted to allow the user to select EITHER a single male or female connector from either list. But I also wanted the two lists to scroll "in lockstep" using arrow keys, or slaved to a single common scroll-bar. And also, the total number of connectors pairs is fluid and may change over time.
I ended up storing the two lists on a hidden sheet, under two named ranges. The code ends up clearing and reloading two Listboxes from the two named ranges accoridng to events.
Hard to 'splain. If anyone wants to play (it's actually pretty neat) here's the code:
Code:
Private Const Display_Lines As Long = 10
Private L_1 As String
Private L_2 As String
Private Sub ListBox1_Click()
Me.ListBox2.ListIndex = -1
L_2 = ""
End Sub
Private Sub ListBox2_Click()
Me.ListBox1.ListIndex = -1
L_1 = ""
End Sub
Private Sub ListBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 40 'down
If Me.ListBox1.ListIndex = Me.ListBox1.ListCount - 1 And _
Me.ScrollBar1.Value < Me.ScrollBar1.Max Then
Me.ScrollBar1.Value = Me.ScrollBar1.Value + 1
Me.ListBox1.ListIndex = Me.ListBox1.ListCount - 1
End If
Case 38 'up
If Me.ListBox1.ListIndex = 0 And _
Me.ScrollBar1.Value > 1 Then
Me.ScrollBar1.Value = Me.ScrollBar1.Value - 1
Me.ListBox1.ListIndex = 0
End If
Case 39 'right
Me.ListBox2.ListIndex = Me.ListBox1.ListIndex
Me.ListBox1.ListIndex = -1
L_1 = ""
Me.ListBox2.SetFocus
End Select
End Sub
Private Sub ListBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 40 'down
If Me.ListBox2.ListIndex = Me.ListBox2.ListCount - 1 And _
Me.ScrollBar1.Value < Me.ScrollBar1.Max Then
Me.ScrollBar1.Value = Me.ScrollBar1.Value + 1
Me.ListBox2.ListIndex = Me.ListBox2.ListCount - 1
End If
Case 38 'up
If Me.ListBox2.ListIndex = 0 And _
Me.ScrollBar1.Value > 1 Then
Me.ScrollBar1.Value = Me.ScrollBar1.Value - 1
Me.ListBox2.ListIndex = 0
End If
Case 37 'left
Me.ListBox1.ListIndex = Me.ListBox2.ListIndex
Me.ListBox2.ListIndex = -1
L_2 = ""
Me.ListBox1.SetFocus
End Select
End Sub
Private Sub ScrollBar1_Change()
If Not Me.ListBox1.Value = "" Then
L_1 = Me.ListBox1.Value
End If
If Not Me.ListBox2.Value = "" Then
L_2 = Me.ListBox2.Value
End If
Stp = False
Me.ListBox1.Clear
Me.ListBox2.Clear
For Cnt = Me.ScrollBar1.Value To Me.ScrollBar1.Value + Display_Lines - 1
Me.ListBox1.AddItem Range("Special_List_m").Item(Cnt).Value
Me.ListBox2.AddItem Range("Special_List_s").Item(Cnt).Value
Next Cnt
On Error Resume Next
Me.ListBox1.Value = L_1
Me.ListBox2.Value = L_2
On Error GoTo 0
Stp = True
End Sub
Private Sub UserForm_Initialize()
L_1 = ""
L_2 = ""
Me.ScrollBar1.Min = 1
Me.ScrollBar1.Max = Range("Special_List_m").Count - Display_Lines + 1
Me.ScrollBar1.LargeChange = Me.ScrollBar1.Max / 5
Me.ScrollBar1.Value = 1
End Sub
To make it work, you need (2) listboxes and a scrollbar, sid-by-side-by-side on a userform. The height of all three should be set to 105, so teh displayed lines fill up the complete control without causing the native vertical scrollbar to be displayed. And you need to lists in teh workbook called Special_List_m and Special_List_s, having the same number of members each.
Not very spectacular, however, as with any well-designed UI, it's subtle, effective and natural for the user.