Well I thought I would easily find a tutorial on this, but am struggling all over the net to find a good reference.
All my programming I have learned is from tutorials...so im a novice.
Im sure the title says it all what im trying to do. I have a button. You click the button and it populates a listview box that has 2 columns in it. After the listview box is populated the focus is set to the listview box.
I am trying to figure out the keypress code that will allow the user to type 1-3 characters and the program will search and highlight the closest matching to the keys pressed.
I do not want to use a text box...I just want the user to be able to hit "M" and it just to the first "M" item in the list then user presses "I" and maybe it jumps to the first "Michael" record in the list..etc.
As far as I'm aware the listbox only has a very basic version of this (typing a letter it will go to the first entry that begins with that letter). If you are a novice, overriding the keypress and writing you own search algorithm might be a bit of a step to far.
You may want to consider just using a combo box instead, which has this functionality built in with the settings:
Unfortunatly a combo box wont work for this particular program...I mean technically it would, but with it only displaying 1 item at a time...we really need to view a block of data at once which is why I went with the listview box.
I just want the user to be able to hit "M" and it just to the first "M" item in the list then user presses "I" and maybe it jumps to the first "Michael" record in the list..etc.
Thank you for any help or advise.
I was thinking of doing that for one of my LV apps but never implemented it so not fully tested. The idea was to store the keys in a string and display them in a lable so I knew what was currently being used to select the LV items, ESC key to reset/start over, backspace to clear last key entered, thats as far as I got, code changed to allow 3 keys max...
Code:
Private last3Keys As String = String.Empty
Private Sub ListView1_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles ListView1.KeyPress
' discard the keypress so LV doesn't select anything.
e.Handled = True
' if escape key pressed then clear saved keys (reset/start over).
If e.KeyChar = ChrW(Keys.Escape) Then ' clear saved keys
last3Keys = String.Empty
' if backspace key then remove last key or clear.
ElseIf e.KeyChar = ChrW(Keys.Back) Then
If last3Keys.Length = 1 Then
last3Keys = String.Empty
ElseIf last3Keys.Length > 1 Then
last3Keys = last3Keys.Substring(0, last3Keys.Length - 1)
End If
Else
' if no keys saved or we have 3 keys then reset/start over
If last3Keys.Length = 0 OrElse last3Keys.Length > 2 Then
last3Keys = e.KeyChar.ToString.ToLower
Else ' add key
last3Keys &= e.KeyChar.ToString.ToLower
End If
End If
' show pressed keys in a lable
LblLast3KeyPresses.Text = last3Keys.ToUpper
' unselect all LV items
ListView1.SelectedItems.Clear()
If last3Keys.Length > 0 Then
' find and select item(s) starting with keys
For i As Integer = 0 To ListView1.Items.Count - 1
' if item starts with keys select it
If ListView1.Items.Item(i).Text.ToLower.StartsWith(last3Keys) Then
ListView1.Items(i).Selected = True ' select item
' make sure we can see the selected item(s)
ListView1.EnsureVisible(i)
' if LV not multiselect then exit loop
If ListView1.MultiSelect = False Then Exit For
End If
Next
End If
End Sub
I was thinking of doing that for one of my LV apps but never implemented it so not fully tested. The idea was to store the keys in a string and display them in a lable so I knew what was currently being used to select the LV items, ESC key to reset/start over, backspace to clear last key entered, thats as far as I got, code changed to allow 3 keys max...
Code:
Private last3Keys As String = String.Empty
Private Sub ListView1_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles ListView1.KeyPress
' discard the keypress so LV doesn't select anything.
e.Handled = True
' if escape key pressed then clear saved keys (reset/start over).
If e.KeyChar = ChrW(Keys.Escape) Then ' clear saved keys
last3Keys = String.Empty
' if backspace key then remove last key or clear.
ElseIf e.KeyChar = ChrW(Keys.Back) Then
If last3Keys.Length = 1 Then
last3Keys = String.Empty
ElseIf last3Keys.Length > 1 Then
last3Keys = last3Keys.Substring(0, last3Keys.Length - 1)
End If
Else
' if no keys saved or we have 3 keys then reset/start over
If last3Keys.Length = 0 OrElse last3Keys.Length > 2 Then
last3Keys = e.KeyChar.ToString.ToLower
Else ' add key
last3Keys &= e.KeyChar.ToString.ToLower
End If
End If
' show pressed keys in a lable
LblLast3KeyPresses.Text = last3Keys.ToUpper
' unselect all LV items
ListView1.SelectedItems.Clear()
If last3Keys.Length > 0 Then
' find and select item(s) starting with keys
For i As Integer = 0 To ListView1.Items.Count - 1
' if item starts with keys select it
If ListView1.Items.Item(i).Text.ToLower.StartsWith(last3Keys) Then
ListView1.Items(i).Selected = True ' select item
' make sure we can see the selected item(s)
ListView1.EnsureVisible(i)
' if LV not multiselect then exit loop
If ListView1.MultiSelect = False Then Exit For
End If
Next
End If
End Sub
I will play with the code and report anything I find back to you...thank you both for the help so far. Thanks Enrico for the links...I have been reading them and playing around with those as well.
I initially thought u wanted the items highlighted with a custom color.. Which i thought would be cake...
Errr.. not for me lmao..
But I found a post for that if your interested and i made a working model of the thing you were trying to accomplish..
I used Edgemeal idea for esc & backspace.. Tried to incorporate the color thing but i couldnt get it..
Note: If you do attempt to do the color thing there is a mis-type i believe on line 41 of the colorListbox class.. It read itemDate which I'm sure shouldve been itemData..
Private catchKey As New KeyPressEventHandler(AddressOf GetKeyPress)
Private searchTerm As String = Nothing
Private Sub GetKeyPress(sender As System.Object, ByVal e As KeyPressEventArgs)
'Check for the back key
If Asc(e.KeyChar) = 8 And Not IsNothing(searchTerm) Then
searchTerm = searchTerm.Remove(searchTerm.Count - 1, 1)
'Check for the escape key
ElseIf Asc(e.KeyChar) = 27 Then
ClearListBox(sender, System.EventArgs.Empty)
End If
'Check to see we have a character and not something like capslock
If Asc(e.KeyChar) > 33 And Asc(e.KeyChar) < 126 Then
If IsNothing(searchTerm) Then
searchTerm = e.KeyChar
Else
If searchTerm.Count = 3 Then
searchTerm = Nothing
GetKeyPress(sender, e)
Exit Sub
End If
searchTerm &= e.KeyChar
End If
End If
Me.CurSrchTrm_Label.Text = searchTerm
highlightSearch(searchTerm)
End Sub
Private Sub Form1_Click(sender As System.Object, e As System.EventArgs) Handles MyBase.Click
Val2SrchBrdr_Panel.Focus()
End Sub
Private Sub ClearListBox(sender As System.Object, e As System.EventArgs) Handles ResetListBox_But.Click
Me.Vals2Srch_ListBox.Items.Clear()
searchTerm = Nothing
End Sub
Private Sub AddNewVal_But_Click(sender As System.Object, e As System.EventArgs) Handles AddNewVal_But.Click
Me.Vals2Srch_ListBox.Items.Add(Me.NewVals_TxtBox.Text)
Me.NewVals_TxtBox.Text = Nothing
End Sub
Private Sub Vals2Srch_ListBox_Focus(sender As System.Object, e As System.EventArgs) Handles Vals2Srch_ListBox.GotFocus
Me.Val2SrchBrdr_Panel.BackColor = Color.Red
AddHandler Me.Vals2Srch_ListBox.KeyPress, catchKey
End Sub
Private Sub Vals2Srch_ListBox_NoFocus(sender As System.Object, e As System.EventArgs) Handles Vals2Srch_ListBox.LostFocus
Me.Val2SrchBrdr_Panel.BackColor = Color.FromKnownColor(KnownColor.Control)
RemoveHandler Me.Vals2Srch_ListBox.KeyPress, catchKey
End Sub
'Credit: http://www.vbforums.com/showthread.php?578364-Colored-ListBox-(custom-fonts-colors-highlight)-Updated!-Now-With-Class!
'Private Sub highlightSearch(ByVal searchStr As String)
' For Each itemObj As ItemData In Me.Vals2Srch_ListBox.Items
' If Not (itemObj.Item.ToLower.IndexOf(searchTerm.ToLower) = -1) Then
' itemObj.ItemColor = Color.Yellow
' End If
' Next
'End Sub
Private Sub highlightSearch(ByVal searchStr As String)
Dim itemsSelectedList As New ArrayList
Dim itemIndex As Integer = 0
TestList_ListBox.Items.Clear()
For Each itemObj As String In Me.Vals2Srch_ListBox.Items
If Not (itemObj.ToLower.IndexOf(searchStr.ToLower) = -1) Then
TestList_ListBox.Items.Add(itemObj)
itemsSelectedList.Add(itemIndex)
'itemObj.ItemColor = Color.Yellow
End If
itemIndex += 1
Next
Me.Vals2Srch_ListBox.SelectedItem = Nothing
For Each i As Integer In itemsSelectedList
Me.Vals2Srch_ListBox.SetSelected(i, True)
Next
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.CurSrchTrm_Label.Text = Nothing
End Sub