Dev Catalin
Dev Catalin

Reputation: 1325

Search listview items using a textbox

I am trying to make a search box for my listview and I managed to make an algorithm that works but not perfectly:

if (!string.IsNullOrWhiteSpace(searchBox.Text))
{
    foreach (ListViewItem item in textureViewer.Items)
    {
        if (!item.Text.ToLower().Contains(searchBox.Text.ToLower()))
            textureViewer.Items.Remove(item);
    }
    if (textureViewer.SelectedItems.Count == 1)
    {
        textureViewer.Focus();
    }
}
else
    LoadTextures();

So far, it works, I can search for items and they are displayed well but, for example if I search for "sword_diamond" and then remove "_diamond" so now I have in my searchBox only "sword" , it won't show me all the "sword" textures because I have already deleted them from my listview so I'll have to delete everything from the searchBox so it will refresh. I wanted to try to hide the items, store the info which items are hid and at each step when a letter is deleted to make them appear. Unfortunately, item.Visible is not available for me and I don't think it would be a good algorithm.

Can you help me? Thanks

Upvotes: 0

Views: 3236

Answers (2)

Alberto Monteiro
Alberto Monteiro

Reputation: 6219

Save you images list in a field on form, then use it to filter, like that

private IEnumerable<string> textures;

private void Form1_Load(object sender, EventArgs e)
{
    this.textures = LoadTextures();
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (!string.IsNullOrWhiteSpace(textBox1.Text))
    {
        FillListView(item => item.ToLower().Contains(textBox1.Text.ToLower()));

        if (listView1.SelectedItems.Count == 1)
            listView1.Focus();
    }
    else
        FillListView();
}

private void FillListView(Func<string, bool> filter = null)
{
    listView1.Items.Clear();
    var items = filter == null ? this.textures : this.textures.Where(filter);
    foreach (var item in items)
        listView1.Items.Add(item);
}

private IEnumerable<string> LoadTextures()
{
    return Directory.GetFiles("path", "*.png");
}

Upvotes: 0

Yacoub Massad
Yacoub Massad

Reputation: 27861

You should use the ListView to display the results of the search, not to store the original data.

To store the original data, put them in some collection, for example a List<string> in an instance variable.

And every time you search, you can use LINQ to filter the data and then you can put the results into the ListView.

Here is an example:

Assuming that you store the data in some instance variable data:

var results = data.Where(x => x.Contains("sword")).ToList();

And then you would use results to fill the list view.

This way, data would always contain the original data (unfiltered). And for each search, you calculate a new data set just to display it in the ListView.

Upvotes: 2

Related Questions