Background: I am building a database application to store information about my massive movie collection. The listbox contains hundreds of items so I decided to implement a search feature which would highlight all items that contain a particular string. Sometimes it's hard to remember an entire movie title so I thought this would co开发者_运维知识库me in handy.
I found this useful code on the Microsoft site that highlights all items in a listbox that contain a particular string. How can I modify it to search through each string entirely?
Currently the code only searches for items that start with the search string, instead of seeing if it contains the search string anywhere else. I came across a listbox.items.contains() kind of method on Google, although I have no idea how to convert my code for it.
http://forums.asp.net/t/1094277.aspx/1
private void FindAllOfMyString(string searchString)
{
// Set the SelectionMode property of the ListBox to select multiple items.
listBox1.SelectionMode = SelectionMode.MultiExtended;
// Set our intial index variable to -1.
int x =-1;
// If the search string is empty exit.
if (searchString.Length != 0)
{
// Loop through and find each item that matches the search string.
do
{
// Retrieve the item based on the previous index found. Starts with -1 which searches start.
x = listBox1.FindString(searchString, x);
// If no item is found that matches exit.
if (x != -1)
{
// Since the FindString loops infinitely, determine if we found first item again and exit.
if (listBox1.SelectedIndices.Count > 0)
{
if(x == listBox1.SelectedIndices[0])
return;
}
// Select the item in the ListBox once it is found.
listBox1.SetSelected(x,true);
}
}while(x != -1);
}
}
Create your own search function, something along the lines of
int FindMyStringInList(ListBox lb,string searchString,int startIndex)
{
for(int i=startIndex;i<lb.Items.Count;++i)
{
string lbString = lb.Items[i].ToString();
if(lbString.Contains(searchString))
return i;
}
return -1;
}
(beware, I wrote this out of my head without compiling or testing, the code may contain bugs, but I think you will get the idea!!!)
Use String.IndexOf for a case-insenstive string search on each item in your ListBox:
private void FindAllOfMyString(string searchString) {
for (int i = 0; i < listBox1.Items.Count; i++) {
if (listBox1.Items[i].ToString().IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0) {
listBox1.SetSelected(i, true);
} else {
// Do this if you want to select in the ListBox only the results of the latest search.
listBox1.SetSelected(i, false);
}
}
}
I also suggest they you set your ListBox's SelectionMode property in the Winform designer, or in your forms constructor method.
I'm not sure about the code you posted, but I wrote a small method to do what you're looking for. It's extremely simple:
private void button1_Click(object sender, EventArgs e)
{
listBox1.SelectionMode = SelectionMode.MultiSimple;
IEnumerable items = listBox1.Items;
List<int> indices = new List<int>();
foreach (var item in items)
{
string movieName = item as string;
if ((!string.IsNullOrEmpty(movieName)) && movieName.Contains(searchString))
{
indices.Add(listBox1.Items.IndexOf(item));
}
}
indices.ForEach(index => listBox1.SelectedIndices.Add(index));
}
What about the below. You just need to improve it a bit
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public class Item
{
public Item(string id,string desc)
{
id = id;
Desc = desc;
}
public string Id { get; set; }
public string Desc { get; set; }
}
public partial class Form1 : Form
{
public const string Searchtext="o";
public Form1()
{
InitializeComponent();
listBox1.SelectionMode = SelectionMode.MultiExtended;
}
public static List<Item> GetItems()
{
return new List<Item>()
{
new Item("1","One"),
new Item("2","Two"),
new Item("3","Three"),
new Item("4","Four")
};
}
private void Form1_Load(object sender, EventArgs e)
{
listBox1.DataSource = GetItems();
listBox1.DisplayMember = "Desc";
listBox1.ValueMember = "Id";
listBox1.ClearSelected();
listBox1.Items.Cast<Item>()
.ToList()
.Where(x => x.Desc.Contains("o")).ToList()
.ForEach(x => listBox1.SetSelected(listBox1.FindString(x.Desc),true));
}
}
}
Same question was asked: Search a ListBox and Select result in C#
I propose another solution:
Not good for listbox > 1000 items.
Each iteration loops all items.
Finds and stays on most suitable case.
// Save last successful match. private int lastMatch = 0; // textBoxSearch - where the user inputs his search text // listBoxSelect - where we searching for text private void textBoxSearch_TextChanged(object sender, EventArgs e) { // Index variable. int x = 0; // Find string or part of it. string match = textBoxSearch.Text; // Examine text box length if (textBoxSearch.Text.Length != 0) { bool found = true; while (found) { if (listBoxSelect.Items.Count == x) { listBoxSelect.SetSelected(lastMatch, true); found = false; } else { listBoxSelect.SetSelected(x, true); match = listBoxSelect.SelectedValue.ToString(); if (match.Contains(textBoxSearch.Text)) { lastMatch = x; found = false; } x++; } } } }
Hope this help!
just one liner
if(LISTBOX.Items.Contains(LISTBOX.Items.FindByText("anystring")))
//string found
else
//string not found
:) Regards
精彩评论