带有 TextChanged 事件的 AutoCompleteStringCollection

AutoCompleteStringCollection with TextChanged Event

我目前正在使用文本框来过滤一些条目。我在文本框 TextChanged 事件上更新了显示,因此用户没有按回车键或按下按钮开始过滤。我想使用 AutoCompleteStringCollection 来记住输入到文本框中的条目;但是,如果我在触发 TextChanged 事件时保存文本框中的每个字符串,那么它将存储每个过滤器项的所有子字符串。

例如,如果我输入字符串 "test",它会显示: "t" "te" "tes" "test" 作为推荐的字符串。我只想将最后一个字符串添加到 AutoCompleteStringCollection。

我考虑过可以实施的两种不同的方法。

1) 我可以创建一个 Task,在最后一个 TextChanged 事件之后 等待 "x" 数量 的时间,然后再将字符串添加到 AutoCompleteStringCollection。如果这样做,每次触发 textChanged 事件时,我都必须使用 cancellationToken 来取消任务。这稍微复杂一些,因为我使用的是 .NET 4.0。

2) 我还可以在每次添加字符串时通过 AutoCompleteStringCollection 搜索删除所有子字符串(从开头开始的词)。如果用户键入更具体的过滤器,但仍想存储较短的过滤器,这可能会适得其反。

有没有更好的方法来做到这一点?您会推荐哪种方法?

尝试动态填充 AutoCompleteStringCollection 时需要注意两件事。首先是 Microsoft 对此问题的解决方案:

Do not modify the AutoComplete candidate list dynamically during key events. (MSDN)

话虽如此,我还是找到了一种动态向列表添加元素的方法。

我最终选择了任务实现的修改版本。我没有使用 CancellationToken 和 TokenSource,而是使用了 bool。我的代码最终大致如下所示:

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

您还需要在 textChanged 事件处理程序中编写代码,以便在他们开始在文本框中键入时将 bool 设置为 false。这样您就不会在第一个文本更改事件后 4 秒添加第一个条目。

要注意的第二件事是,如果我使用 AutoCompleteMode.SuggestAppend 或追加,则会出现违规异常。

虽然这不是一个完整的答案,但我希望它能帮助任何设法找到这个问题的人。