Speerian
Speerian

Reputation: 1208

AutoCompleteStringCollection with TextChanged Event

I'm currently using a text box to filter some entries. I have the display updating on the text box TextChanged event, so the user isn't hitting enter or pressing a button to begin filtering. I want to use an AutoCompleteStringCollection to remember entries typed into the text box; however, if I save every string from the text box when the TextChanged event is fired then it will store all the substrings of each filter term.

So for instance, if I typed the string "test" it would display: "t" "te" "tes" "test" as recommended strings. I just want the last string added to the AutoCompleteStringCollection.

I've thought about two separate methods I could implement.

1) I could create a Task that waits "x" amount of time after the last TextChanged event before it adds the string to the AutoCompleteStringCollection. If I did this I would have to use a cancellationToken to cancel the Task every time the textChanged event fired. This is slightly more complicated because I'm using .NET 4.0.

2) I could also search through the AutoCompleteStringCollection every time a string is added and remove all substrings (that start at the beginning of the word). This may backfire if the user types in a more specific filter, but still wants to store the shorter one.

Is there a better way to go about doing this? Which method would you recommend?

Upvotes: 0

Views: 584

Answers (1)

Speerian
Speerian

Reputation: 1208

There are two things to be aware of when trying to dynamically fill the AutoCompleteStringCollection. First is Microsoft's Resolution to the issue:

Do not modify the AutoComplete candidate list dynamically during key events. (MSDN)

Having said that, I was able to figure out a way to dynamically add elements to the list.

I ended up opting for a modified version of the Task implementation. Instead of using a CancellationToken and TokenSource I used a bool. My code ended up looking roughly like this:

private void AddSearchToDropDown ()
   {
      Task.Factory.StartNew (() =>
      {
         if (CanAdd && filterTxtBox.Text.Length > 2)
         {
            CanAdd = false;
            Thread.Sleep (4000);
            this.Invoke(new Action(() =>
            {
               filterTxtBox.AutoCompleteMode = AutoCompleteMode.None;
               m_suggestedTests.Add (filterTxtBox.Text);
               filterTxtBox.AutoCompleteMode = AutoCompleteMode.Suggest;
               CanAdd = true;
             }));
         }
      });
   }

You'll also want code in your textChanged event handler that will set the bool to false whenever they begin typing in the textbox. That way you don't add the first entry 4 seconds after the first text changed event.

Second thing to be aware of is that there was a Violation Exception if I used AutoCompleteMode.SuggestAppend or Append.

While this isn't a complete answer I hope that it helps anyone that manages to find this question.

Upvotes: 1

Related Questions