Как сделать поиск по listbox, по слову или части слова? Например: в textbox1 пишем слово "man" и нажимаем на кнопку "Search" и нужно, чтоб нашло слово или часть слова, в listbox1 и перешло на строку с этим словом. И чтоб по нажатию кнопки "Search" еще раз, чтоб нашлась следующая строка содержащая это слово. И если дальше в списке нету строки с этим словом, тогда нужно чтоб поиск шел по кругу и переходил на первую строку с этим словом в listbox. То есть, чтоб поиск происходил по кругу в listbox, по нажатию кнопки "Search".
(Если можно, объясните как для новичка). В общем нужна такая же функция как в кнопке "Найти далее" в блокноте.
Сделал вот так, но работает неправильно, проходит по всем вариантам которые есть в listbox и останавливается на последнем:
private void buttonFindNext_Click(object sender, EventArgs e)
{
Form1 main = this.Owner as Form1;
if (main != null)
for (int i = 0; i < main.listBox1.Items.Count; i++)
{
if (main.listBox1.Items[i].ToString().ToLower().Contains(textBoxSearch.Text))
{
main.listBox1.SetSelected(i, true);
}
}
}
Как сделать чтоб находил только один вариант, а по нажатию кнопки "найти далее" переходил на следующий найденный текст, который ввели в textBoxSearch?
Для поиска с продолжением, вам необходимо запоминать последнее найденное положение. В вашем случае это будет индекс элемента ListBox. Для того, чтобы значение сохранялось между кликами по кнопке, нужно завести отдельное поле в классе формы. Для простоты, пусть все элементы размещены на одной форме, тогда решение может выглядеть так:
private int lastFoundIndex = -1;
private void buttonFindNext_Click(object sender, EventArgs e)
{
int i;
for (i = lastFoundIndex + 1; i < listBox1.Items.Count; i++)
{
var currVal = listBox1.Items[i].ToString();
if(currVal.IndexOf(textBoxSearch.Text, StringComparison.OrdinalIgnoreCase) > -1)
{
listBox1.SetSelected(i, true);
lastlastFoundIndex = i;
break;//прерываем цикл
}
}
if(lastFoundIndex > -1 && i == listBox1.Items.Count)
{
for (i = 0; i <= lastFoundIndex; i++)
{
var currVal = listBox1.Items[i].ToString();
if(currVal.IndexOf(textBoxSearch.Text, StringComparison.OrdinalIgnoreCase) > -1)
{
listBox1.SetSelected(i, true);
lastlastFoundIndex = i;
break;//прерываем цикл
}
}
}
}
Теперь немного расшифрую "магию"
Начальное значение lastFoundIndex выбрано -1, т.к. индексы коллекций и перечислений начинаются с 0, а значит такого значения среди индексов быть не может, что и будет означать, что поиск не дал результатов.
Случай первый: элементов нет. В этом случае первый цикл пройдет по всем элементам до конца, значение lastFoundIndex не изменится, второй цикл выполнен не будет согласно условию.
Случай второй: есть один и более искомых элементов. При первом поиске, первый цикл выполнится до первого найденного значения, изменит состояние lastFoundIndex и прервет цикл. Следующий цикл не выполнится, т.к. первый еще не дошел до конца. Допустим мы нашли последний или единственный элемент. При следующем поиске первый цикл начнется со значения lastFoundIndex + 1, т.е. следующего за предыдущим найденным, дойдет до конца, и начнет выполнятся второй цикл с 0, до последнего найденного индекса. Если элемент был всего один, то мы вернемся на то же место, если нет, то на первый найденный с начала списка элемент.
Если текст для поиска изменился, необходимо выставить значение lastFoundIndex обратно в -1.
Вместо приведения к нижнему регистру, при котором будет создана еще одна строка, я воспользовался перегрузкой метода String.IndexOf(String.IndexOf (String, StringComparison), во втором параметре которого указывается одно из возможных правил поиска, в данном случае игнорировать регистр.
@rdorn: Спасибо большое. Код немного подправил, не знаю или все правильно сделано, но код работает как надо.
private int lastFoundIndex = -1;
private void buttonFindNext_Click(object sender, EventArgs e)
{
Form1 main = this.Owner as Form1;
if (main != null)
{
int i;
for (i = lastFoundIndex + 1; i < main.listBox1.Items.Count; i++)
{
var currVal = main.listBox1.Items[i].ToString();
if (currVal.ToLower().Contains(textBoxSearch.Text.ToLower()))
{
main.listBox1.SetSelected(i, true);
lastFoundIndex = i;
break;//прерываем цикл
}
}
if (lastFoundIndex > -1 && i == main.listBox1.Items.Count)
{
for (int s = 0; s <= lastFoundIndex; s++)
{
var currVal = main.listBox1.Items[s].ToString();
if (currVal.ToLower().Contains(textBoxSearch.Text.ToLower()))
{
main.listBox1.SetSelected(s, true);
lastFoundIndex = s;
break;//прерываем цикл
}
}
}
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости