C# 文本框自动完成无法正常工作

C# 文本框自动完成无法正常工作,c#,autocomplete,textbox,C#,Autocomplete,Textbox,我正试图实现一个文本框自动完成与一个自定义数据源的形式,一个数组,它显示了单字符输入的建议。但是当我运行程序时,自动完成只在第二个字符输入后开始。当我调试时,我看到数据在AutoCompleteNameCollection中,但直到第二个字符输入时,它才显示在建议中 这段代码是我在textchange事件中编写的 arr = LoadName(empid_txt.Text.Trim()); //arr is string array name

我正试图实现一个文本框自动完成与一个自定义数据源的形式,一个数组,它显示了单字符输入的建议。但是当我运行程序时,自动完成只在第二个字符输入后开始。当我调试时,我看到数据在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,如:nameCollection.Add(“”);它确实适用于单字符输入,但有时会给出AccessViolationException:尝试读取或写入受保护内存。
那么有什么办法可以解决这个问题吗?

如果在初始化文本框时“arr”为空,那么就没有什么可比较的了。在开始键入之前,必须初始化为有效数组。当用户已键入字符时,您正在textchange事件中初始化


在初始化中更改代码之前,需要填充名称集合。

AutoComplete
建议在按下第二个字符后填充名称集合是正常的,因为首先,您已将
arr
(自定义数据源)初始化为空数组。您已经在
TextChanged
事件中填充了
arr
,这就是为什么
AutoComplete
在第二个字符处工作,因为您的数据源是根据第一个字符过滤的(这绝对是您不想要的)

这里有一个建议:

  • 在应用程序的
    FormLoad
    事件中,用所有可能的建议填写
    arr
    (我认为建议的来源是数据库,对吗?)。这将允许textbox对您的第一个字符进行建议

  • 输入第一个字符后,在
    TextChanged
    事件中,根据输入的前一个字符重新加载
    arr
    数据源


希望有帮助。

在事件处理程序中设置AutoCompleteSource时,我可以复制访问冲突,看起来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;
}

这就停止了访问冲突。

加载时,您可以在
文本框中填充数据子集(甚至可以缓存以供将来/共享使用)。如果你有一个“最常见”的计数器,你可以使用它。作为限制条件,您甚至可以添加一个虚拟项(如果使用空字符串得到的是访问冲突)。
然后,在
TextChange
事件中,从数据库中读取所需的数据


我只有一个问题:在用户开始键入之前,您不想填充源代码吗?如果存在网络流量问题,则需要移动大量数据。如果您移动了大量数据,那么您的用户将不得不等待他们开始键入内容。可以接受吗?另一方面,如果他们不等待太久,可能数据流并没有那么大,您可以将该逻辑放在表单构造函数的
BackgroundWorker
中(或者离那时不远)。

在表单加载时调用Textbox autocomplete方法

 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;
    }
public void autocompleteData()
{
//SuggestStrings将具有从缓存/db返回字符串数组的逻辑
var CurrentuserId=CloudKaseWSClient.GetUserDetail(tokenUsr、tokenPasswd、Username);
列表l=新列表();
var SearchResults=(“选择数据库查询”).ToList();
foreach(搜索结果中的var i)
{
l、 加上(i.姓名);
}
字符串[]arr=l.ToArray();
AutoCompleteTestringCollection=新的AutoCompleteTestringCollection();
collection.AddRange(arr);
txtSearchUser.AutoCompleteMode=AutoCompleteMode.SuggestAppend;
txtSearchUser.AutoCompleteSource=AutoCompleteSource.CustomSource;
txtSearchUser.AutoCompleteCustomSource=集合;
}
或者,您希望为自动完成文本框设置静态数据,而不是在设计视图中为自动完成模式的文本框属性设置SuggestAppend,自动完成源设置CustomSource,并在CompleteCustomSource中添加静态值

我希望这个解决方案对你有帮助。。
快乐编码。:)

您是否要求我在用户开始键入之前加载所有数据。如果是这样,我就不能这样做,因为我可以在textchange事件中过滤大量数据。除非有匹配的内容,否则textbox无法自动完成。由于在用户键入内容之前不会填充源代码,因此它不会在第一个字符上自动完成。您可以尝试筛选一个上游事件(即KeyDown事件),但当我最初使用空字符串(而不是字符串数组)填充源,然后在文本更改中使用字符串数组替换/追加它时,它确实起作用。。。但是,有时它会给出访问冲突异常。你知道有什么解决办法吗?我不想把所有的东西都放在表单加载事件中…当要检索的数据很大时,它会导致太多的网络拥塞,并且需要大量的带宽,所以我只使用文本更改事件…此外,正如我所说,当我在表单加载事件中初始化它时,它确实适用于单字符输入首先使用空字符串,然后在文本更改事件中将数据源更改为字符串数组…但它不稳定,因为它有时会出现上述异常。是的,数据源实际上是一个数据库。我对textbox也有同样的问题,对我来说,我使用multiline with textbox导致了这个问题。将多行更改为false s