TextBox自动完成功能无法正常工作
本文关键字:常工作 工作 成功 功能 TextBox | 更新日期: 2023-09-27 18:26:13
我正试图用一个数组形式的自定义数据源实现一个文本框自动完成,该数组显示了对单字符输入的建议。但当我运行程序时,自动完成只在第二个字符输入后开始。当我调试时,我看到AutoCompleteNameCollection中有数据,但直到第二个字符输入时,它才显示在建议中。
这段代码是我在textchange事件中写的。
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;
在LoadEvent中,我用一个空数组初始化了AutoCompleteNameCollection。
namesCollection.AddRange(arr);// here arr is empty
empid_txt.AutoCompleteMode = AutoCompleteMode.Suggest;
empid_txt.AutoCompleteSource = AutoCompleteSource.CustomSource;
empid_txt.AutoCompleteCustomSource = namesCollection;
但它直到第二个字符输入才起作用。但是,如果不是数组,而是用一个空字符串初始化AutoCompleteNameCollection,如:namesCollection.Add(");它确实适用于单字符输入,但有时会出现AccessViolationException:试图读取或写入受保护的内存。那么,有什么办法可以解决这个问题吗?
在事件处理程序中设置AutoCompleteSource时,我可以复制访问冲突,看起来自动完成例程可能正在访问AutoCompleteSource,而它正在被替换和销毁。
为了防止这种情况,你可以在你的代码周围加一个锁。
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;
}
这阻止了访问冲突。
加载时,您可以用数据的子集填充TextBox
(甚至可以缓存以供将来/共享使用)。如果你有一个"最常见"的计数器,你可以使用它。作为限制条件,你甚至可以添加一个伪项(如果你用空字符串得到的是访问违规)。然后,在TextChange
事件上,从数据库中读取所需的数据。
我只有一个问题:在用户开始键入之前,您不想填充源?如果存在网络流量问题,那么您会移动大量数据。如果你移动了大量数据,那么你的用户将不得不等待他们开始键入内容。可以接受吗?另一方面,如果他们没有等待太多,也许数据流没有那么大,你可以把这个逻辑放在表单构造函数的BackgroundWorker
中(或者离那个时候不远)。
AutoComplete
建议在按下第二个字符后是正常的,因为首先,您已经将arr
(它是您的自定义数据源)初始化为一个空数组。您已经在TextChanged
事件中填充了arr
,这就是为什么AutoComplete
在第二个字符处工作,因为您的数据源是根据第一个字符进行筛选的(这肯定是您不想要的)。
这里有一个建议:
-
在应用程序的
FormLoad
事件中,用所有可能的建议填充arr
(我认为建议的来源来自数据库,对吗?)。这将允许文本框在您的第一个字符上提出建议。 -
输入第一个字符后,在
TextChanged
事件中,根据输入的前一个字符重新加载arr
数据源。
希望能有所帮助。
如果在初始化文本框时"arr"为空,则没有可比较的内容。在开始键入之前,必须将AutoCompleteCustomSource初始化为有效数组。当用户已经键入字符时,您正在textchange事件中进行初始化。
在初始化中更改代码之前,您需要填充namesCollection。
在Form Load中调用Textbox自动完成方法。
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;
}
或者,如果要为"自动完成"文本框设置静态数据,则必须在"设计"视图中为AutocompleteMode的文本框属性设置SuggestAppend,AutocompleteSource设置CustomSource并在AutocompleteCustomSource中添加静态值。
我希望这个解决方案对你有帮助。。快乐编码。:)