I am trying to implement a textbox autocomplete with a custom datasource in the form of an array which shows suggestions on single character input. But when i run the progra
I can replicate the access violation when setting the AutoCompleteSource in the event handler, it seems like the autocomplete routine may be accessing the AutoCompleteSource while it is being replaced and destroyed.
To prevent this you can put a lock around your code.
lock(this)
{
arr = LoadName(empid_txt.Text.Trim()); //arr is string array
namesCollection.AddRange(arr);
this.empid_txt.AutoCompleteMode = AutoCompleteMode.Suggest;
this.empid_txt.AutoCompleteSource = AutoCompleteSource.CustomSource;
this.empid_txt.AutoCompleteCustomSource = namesCollection;
}
This stopped the access violations.
AutoComplete
suggests after the second char is being pressed is normal because in the first place, you have initialized the arr
(which is your custom datasource) into an empty array. You have populated your arr
in TextChanged
event and that's why AutoComplete
works at the second char because your datasource is filtered based on your first char (which is definitely what you don't want).
Here's a suggestion:
On the FormLoad
event of your application, fill arr
with all the possible suggestions (I think the source of suggestion is from database right?). This will allow textbox to suggest on your first char.
When you have entered the first char, on the TextChanged
event reload your arr
datasource based on the prevous character being entered.
Hope it helps.
On Form Load call the Textbox autocomplete method.
public void autocompleteData()
{
//SuggestStrings will have the logic to return array of strings either from cache/db
var CurrentuserId = CloudKaseWSClient.GetUserDetail(tokenUsr, tokenPasswd, Username);
List<string> l = new List<string>();
var SearchResults = ("Select Database Query").ToList();
foreach (var i in SearchResults)
{
l.Add(i.name);
}
string[] arr = l.ToArray();
AutoCompleteStringCollection collection = new AutoCompleteStringCollection();
collection.AddRange(arr);
txtSearchUser.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
txtSearchUser.AutoCompleteSource = AutoCompleteSource.CustomSource;
txtSearchUser.AutoCompleteCustomSource = collection;
}
OR You want to set static data for AutoComplete Textbox than you have to set In Design view for Textbox property of AutocompleteMode to set SuggestAppend,AutocompleteSource to set CustomSource and add static value inAutocompleteCustomSource.
I hope this solution helps to you.. Happy Coding.:)
On load you may populate the TextBox
with a sub-set of your data (that can be even cached for future/shared use). If you have a "most common" counter you can use it. As limit condition you may even add a dummy item (if what you get with an empty string is an access violation).
Then, on the TextChange
event read the data you need from the database.
I have only one question: you do not want to populate the source until the user starts to type? If there's the problem of network traffic then you move a lot of data. If you move a lot of data then your users will have to wait when they start to type something. Is it acceptable? On the other side if they do not wait too much maybe data stream is not so big and you can put that logic in a BackgroundWorker
in the constructor of your form (or not far from that time).
If 'arr' is empty when you initialize the textbox then there is nothing to compare to. You have to initialize AutoCompleteCustomSource to a valid array before you start typing. You are initializing in textchange event, when the user has already typed a character.
You need to populate the namesCollection before the code is changed - in Initialize.