【问题标题】:TextBox AutoComplete Not working properly文本框自动完成无法正常工作
【发布时间】:2012-03-18 05:15:15
【问题描述】:

我正在尝试使用数组形式的自定义数据源实现文本框自动完成功能,该数组显示有关单字符输入的建议。但是当我运行程序时,自动完成仅在第二个字符输入后开始。当我调试时,我看到 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: Attempted to read or write protected memory。 那么有什么办法可以解决这个问题吗?

【问题讨论】:

  • 我在使用文本框时遇到了同样的问题,对我来说,我使用的是多行文本框,这导致了这个问题。将多行更改为 false 解决了这个问题。

标签: c# autocomplete textbox


【解决方案1】:

如果在初始化文本框时“arr”为空,则没有可比较的内容。在开始输入之前,您必须将 AutoCompleteCustomSource 初始化为一个有效的数组。当用户已经输入了一个字符时,您正在 textchange 事件中进行初始化。

您需要在更改代码之前填充 namesCollection - 在 Initialize 中。

【讨论】:

  • 您是否要求我在用户开始输入之前加载所有数据。如果是这样,我不能这样做,因为我可以在 textchange 事件中过滤大量数据。
  • 直到它有匹配的东西,文本框才能自动完成。由于在用户输入内容之前您不会填充源代码,因此它不会在第一个字符上自动完成。您可以尝试过滤上游事件(即 KeyDown 事件)
  • 但是当我最初用空字符串而不是字符串数组填充源,然后在文本更改中用字符串数组替换/附加它时它确实有效......但是,有时它会给出访问冲突例外 。你知道有什么解决办法吗??
【解决方案2】:

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

这里有一个建议:

  • 在您的应用程序的FormLoad 事件中,用所有可能的建议填写arr我认为建议的来源来自数据库,对吧?)。这将允许文本框建议您的第一个字符。

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

希望对你有帮助。

【讨论】:

  • 我不想把所有的东西都放在表单加载事件中......当要检索的数据很大时,它会导致太多的网络拥塞并且需要大量的带宽,所以我正在使用文本更改事件仅...此外,正如我所说,当我首先使用空字符串在表单加载事件中初始化它,然后在文本更改事件中将数据源更改为字符串数组时,它确实适用于单个字符输入...但它不是稳定,因为它有时会出现上述异常。是的,数据源实际上是一个数据库。
【解决方案3】:

我可以在事件处理程序中设置 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;
}

这停止了访问冲突。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      在表单加载时调用文本框自动完成方法。

       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;
          }
      

      或者您想为 AutoComplete 文本框设置静态数据,而不是在设计视图中为 AutocompleteMode 的 Textbox 属性设置 SuggestAppend,AutocompleteSource 设置 CustomSource 并在 AutocompleteCustomSource 中添加静态值。

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

      【讨论】:

        猜你喜欢
        • 2018-03-01
        • 2011-09-16
        • 1970-01-01
        • 2014-05-18
        • 2020-10-12
        • 2018-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多