Igor
Igor

Reputation: 558

Implementing a find system for a ListView in C#

I am creating an application in C# using a ListView control that lets you create lists. I am implementing a Find function using the Find() method. Here’s my code:

if (findTextBox.Text != "")
{
    ListViewItem[] lviFoundList = listItemsList.Items.Find(findTextBox.Text, true);
    amountFound.Text = "Found " + Convert.ToString(lviFoundList.Count());
    if (lviFoundList.Count() != 0)
    {
        int firstItemIndex = lviFoundList[0].Index;
        listItemsList.Items[firstItemIndex].Selected = true;
    }
}
else
{
    amountFound.Text = "Found 0";
}

However, it doesn’t return any matches. What am I doing wrong?

Upvotes: 0

Views: 242

Answers (3)

Erik
Erik

Reputation: 12858

Honestly, the ListView.Find() method is rather poor and it's much easier to roll your own with LINQ. Think about what Find really is trying to accomplish -- a specific filtering, typically one record.

The first step, if you haven't already, would be to keep a cached collection of your data objects. Let's assume you have a list of Person classes like so:

class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string JobTitle { get; set; }
  public DateTime DateOfBirth { get; set; }
} 

Then in your MainForm you have a ListView and a member variable people defined as a List<Person>. Your ListView.Items should reflect the contents of this List<Person>.

So now maybe you want to find a person based on their FirstName or LastName, right? You could use LINQ in a function like so:

int FindFirstIndexOfPersonNamed(string firstOrLastName)
{
  // WARNING: This is case sensitive!
  return people.FindIndex(p => p.FirstName.Contains(firstOrLastName) || p.LastName.Contains(firstOrLastName));
}

Since your ListView.Items should be reflecting your List<Person> the index should be identical:

// Get the found item and do whatever you want with it...
var selectedListViewItem = listView.Items[index];

Upvotes: 0

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101681

Find method requires your listView item's Name, did you set your list view item's name property? If you want to search for text you can use this:

var lviFoundList = new List<ListViewItem>();
foreach(var item in listItemsList.Items)
{
   if(item.Text == findTextBox.Text) lviFoundList.Add(item);
}

Upvotes: 2

Brandon
Brandon

Reputation: 4593

The Find() Method looks at the ListViewItem's name, not it's text.

You want this instead:

if (findTextBox.Text != "")
{
    List<ListViewItem> items = new List<ListViewItems>();
    foreach ListViewItem lvi in listItemsList.Items
    {
         if (lvi.Text == findTextBox.Text)
            items.Add(lvi);
    }

    amountFound.Text = "Found " + Convert.ToString(lviFoundList.Count());

    if(lviFoundList.Count() != 0)
    {
        int firstItemIndex = lviFoundList[0].Index;
        listItemsList.Items[firstItemIndex].Selected = true;
    }



}
else
{
    amountFound.Text = "Found 0";
}

Upvotes: 0

Related Questions