vb.netlistviewvirtualmode

How-to use FindItemWithText?


Below is the code I am working with. My accounts are stored in a Dictionary(Of String, Integer) so that I can easily associate a value with them. My listview is working great after I converted it to virtualmode but I lost the functionality to search simply by typing in the listview which is what I would like to get back. Without it this makes the whole feature practically useless unless I can search by name. I have searched and implemented multiple examples and I cannot get anything to work. What am I doing wrong? How should it look?

This populates my listview.

Private Sub lstAccounts_RetrieveVirtualItem(sender As Object, e As RetrieveVirtualItemEventArgs) Handles lstAccounts.RetrieveVirtualItem
    lstAccounts.VirtualListSize = MainForm.accounts.Count 'Update after a dictionary edit.

    Dim i As New ListViewItem(MainForm.accounts.Keys(e.ItemIndex))
    If MainForm.accounts.ContainsKey(MainForm.accounts.Keys(e.ItemIndex).ToString) Then
        i.SubItems.Add(MainForm.accounts.Item(i.Text))
    End If
    e.Item = i
End Sub

This is from MSDN. Supposedly required for searching, only example I could find..

Private Sub lstAccounts_SearchForVirtualItem(sender As Object, e As SearchForVirtualItemEventArgs) Handles lstAccounts.SearchForVirtualItem
    Dim x As Double = 0
    If [Double].TryParse(e.Text, x) Then 'check if this is a valid search
        x = Math.Sqrt(x)
        x = Math.Round(x)
        e.Index = Fix(x)
    End If
End Sub

This is also from the MSDN. No matter what I search for it constantly returns null.

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    Dim item1 As ListViewItem = lstAccounts.FindItemWithText(TextBox1.Text)
    If (item1 IsNot Nothing) Then
        MessageBox.Show("Calling FindItemWithText passing" & TextBox1.Text & ": " _
            & item1.ToString())
    Else
        MessageBox.Show("Calling FindItemWithText passing" & TextBox1.Text & ": null")
    End If
End Sub

Solution

  • In your handler for the SearchForVirtualItem event, you must search your dictionary and then tell the ListView the index of the row that matched what was typed.

    Guessing that you want to search the text, you want something like this:

    foreach (var x in MainForm.accounts) {
        if (x.Value == e.Text) {
            e.Index = x.Key;
            return;
        }
    }
    

    BTW, it's better to update the size of the virtual list somewhere else. The handler for the RetrieveVirtualItem event is not the right place to change the size of the list.