Click here to Skip to main content
15,884,237 members
Articles / Programming Languages / Visual Basic
Article

WinForms ListView Find & GetSubItemRect

Rate me:
Please Sign up or sign in to vote.
4.31/5 (11 votes)
23 Jan 20052 min read 101K   1.3K   32   7
Overcoming some limitations of the WinForms ListView control.

Sample Image - LVFind.gif

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.:

VB
For Each itm As ListViewItem In ListView1.Items
    If exactMatch Then
       If itm.Text = mySearchText Then
          ' an exact match was found ...
       End If
    Else
       mySearchText &= "*"
       If itm.Text Like mySearchText Then
          ' a partial match was found ...
       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.:

VB
myRect = ListView1.Items(0).GetBounds(ItemBoundsPortion.Entire)

Unfortunately, ListView SubItem does not, so:

VB
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:

VB
Dim fPar As Integer = LVFind.LVFindItem.LVFI_PARTIAL
Dim mySearchString As String = "findme"
...
Sub Find()
   FindIt(mySearchString, fPar)
End Sub
...
' Search for SearchString in ListView1 Items
Private Sub FindIt(ByVal SearchString As String, _
 Optional ByVal flag As Integer = LVFind.LVFindItem.LVFI_PARTIAL)
   ' Make an instance of the LVFindItem class
   Dim lvf As New LVFind.LVFindItem
   ' Call the LVFnd() sub
   '   1st parm is ListView control
   '   2nd parm is text to find
   '   3rd parm (optional) is flag value (see LVFindItem class for definition)
   lvf.LVFnd(ListView1, SearchString, flag)
   ' Focus the ListView control so we can see which item is selected
   ListView1.Focus()
End Sub

To get the bounding rectangle of a ListView Item or SubItem:

VB
Dim itmIdx As Integer = 1 ' The index of the Item in the Items collection
Dim colNum As Integer = 2 ' The column of the Item or SubItem
Dim myRect As Rectangle ' Holds the return value from Locate()
...
Sub GetRect()
   myRect = Locate(itmIdx, colNum)
End Sub
...
'Get bounding rectangle of Item itm, Column col
Private Function Locate(ByVal itm As Integer, ByVal col As Integer) As Rectangle
   ' Make an instance of the LVFindItem class
   Dim lvf As New LVFind.LVFindItem
   ' A new Rectangle to hold the return value from GetSubItemRect
   Dim rect As New Rectangle
   ' Call the GetSubItemRect() function
   '   1st parm is ListView control
   '   2nd parm is index of Item to find
   '   3rd parm is column of SubItem to find
   '   4th parm (optional) is flag value (see LVFindItem class for definition)
   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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralPublic ListView Problem Pin
Vitoto14-Jul-05 5:56
Vitoto14-Jul-05 5:56 
Generalcompliment for the example Pin
zio_pino7-Jul-05 4:38
zio_pino7-Jul-05 4:38 
QuestionSearch a subitem? Pin
id10t21-Mar-05 11:15
id10t21-Mar-05 11:15 
AnswerRe: Search a subitem? Pin
Stumpy84221-Mar-05 12:27
Stumpy84221-Mar-05 12:27 
GeneralRe: Search a subitem? Pin
khwo16-Jul-06 16:52
khwo16-Jul-06 16:52 
Generalfinding an item that you can't currently see. Pin
JRyon10-Feb-05 10:35
JRyon10-Feb-05 10:35 
GeneralRe: finding an item that you can't currently see. Pin
Anonymous10-Feb-05 11:37
Anonymous10-Feb-05 11:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.