
Introduction
Do you want to find an Item
in a ListView
control without writing a loop to search through the Items
collection? Do you need to get the bounding rectangle of an Item
or SubItem
(in Details view) in a ListView
control? Well then, this article is for you!
Background
VB 6 supports a Find()
method to find an Item
in a ListView
control. However, this method is no longer present in VB.NET. So you could write a code to loop through the Items
collection, comparing each Item
's text with your search text, e.g.:
For Each itm As ListViewItem In ListView1.Items
If exactMatch Then
If itm.Text = mySearchText Then
End If
Else
mySearchText &= "*"
If itm.Text Like mySearchText Then
End If
End If
Next
where mySearchText
is the text you are searching for, and exactMatch
is a Boolean
you've defined to determine if an exact or partial match is to be made. Also, although the ListView Item
supports the GetBounds()
method to return a rectangle with the bounds of the ListView Item
, e.g.:
myRect = ListView1.Items(0).GetBounds(ItemBoundsPortion.Entire)
Unfortunately, ListView SubItem
does not, so:
myRect = ListView1.Items(0).SubItems(1).GetBounds(ItemBoundsPortion.Entire)
produces the following error:
'GetBounds' is not a member of 'System.Windows.Forms.ListViewItem.ListViewSubItem'.
Using the code
To use the LVFindItem
class, add a new class to your project and replace the generated code with the contents of LVFind.vb. Then, in the code for your form containing a ListView
control, add a code similar to the following.
To search for a string in the ListView Items
collection:
Dim fPar As Integer = LVFind.LVFindItem.LVFI_PARTIAL
Dim mySearchString As String = "findme"
...
Sub Find()
FindIt(mySearchString, fPar)
End Sub
...
Private Sub FindIt(ByVal SearchString As String, _
Optional ByVal flag As Integer = LVFind.LVFindItem.LVFI_PARTIAL)
Dim lvf As New LVFind.LVFindItem
lvf.LVFnd(ListView1, SearchString, flag)
ListView1.Focus()
End Sub
To get the bounding rectangle of a ListView Item
or SubItem
:
Dim itmIdx As Integer = 1
Dim colNum As Integer = 2
Dim myRect As Rectangle
...
Sub GetRect()
myRect = Locate(itmIdx, colNum)
End Sub
...
Private Function Locate(ByVal itm As Integer, ByVal col As Integer) As Rectangle
Dim lvf As New LVFind.LVFindItem
Dim rect As New Rectangle
rect = lvf.GetSubItemRect(ListView1, itm, col, LVFind.LVFindItem.LVIR_LABEL)
Return rect
End Function
Points of Interest
Interestingly, on MSDN, under the definition of the LVM_GETSUBITEMRECT
message, the definition of the LVIR_LABEL
flag value states that it is identical to LVIR_BOUNDS
. This is incorrect, at least when the ListView
control is in Details view. Try changing the flag's value in the LVFind
test code (hint: I'm already using LVIR_LABEL
, so change it to LVIR_BOUNDS
and give it a try).
History
23rd Jan 2005 - First release.