How to search the listbox for a word or part of a word? For example: in the textbox1 we write the word "man" and click on the "Search" button and we need to find a word or part of a word in listbox1 and go to the line with this word. And so by clicking the "Search" button again, so that the next line containing this word is found. And if there is no further line with this word in the list, then you need to search in a circle and go to the first line with this word in the listbox. That is, so that the search takes place in a circle in the listbox, by pressing the "Search" button. (If possible, explain how to beginner). In general, you need the same function as in the "Find Next" button in Notepad.
I did it like this, but it works incorrectly, passes through all the options in the listbox and stops at the last one:

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); } } } 

How to make it to find only one option, and by pressing the "find further" button, I proceeded to the next found text, which was entered into textBoxSearch?

  • @rdorn: I haven't tried anything yet, it was supposed to be one question. Only the search window was opened with the textbox and the "find next" button. - Razi85
  • @rdorn: How to make it to find only one option, and by pressing the "find next" button, go to the next found text that was entered into textBoxSearch? - Razi85
  • @rdorn: corrected and added to the first question at the beginning of the topic. - Razi85
  • So much better. I delete the previous comments. for irrelevance - rdorn

2 answers 2

To search with a continuation, you need to memorize the last position found. In your case, this will be the index of the ListBox element. In order for the value to be maintained between clicks on the button, you need to create a separate field in the form class. For simplicity, let all elements be placed on one form, then the solution might look like this:

 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;//прерываем цикл } } } } 

Now a little decipher the "magic"

The initial value of lastFoundIndex is -1, since indexes of collections and enumerations start from 0, which means that such an index cannot be among the indexes, which will mean that the search did not return any results.

Case one: no items. In this case, the first cycle will go through all elements until the end, the value of lastFoundIndex will not change, the second cycle will not be executed according to the condition.

Case two: there are one or more desired items. At the first search, the first cycle will be executed to the first value found, change the state of lastFoundIndex and interrupt the cycle. The next cycle will fail; the first has not yet reached the end. Suppose we found the last or only item. During the next search, the first cycle will start with the value of lastFoundIndex + 1, i.e. following the previous one found, it will reach the end, and the second cycle will start from 0 to the last index found. If there was only one element, we will return to the same place, if not, then the first element found from the beginning of the list.

If the text for the search has changed, you must set the lastFoundIndex value back to -1 .

Instead of reducing to lower case in which another string will be created, I used the overload of the String.IndexOf method (String.IndexOf (String, StringComparison) , in the second parameter of which one of the possible search rules is specified, in this case ignore case.

    @rdorn: Thank you so much. I corrected the code a bit, I don’t know or everything was done correctly, but the code works as it should

     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;//прерываем цикл } } } } }