Reputation: 1208
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
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