带有 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 或追加,则会出现违规异常。
虽然这不是一个完整的答案,但我希望它能帮助任何设法找到这个问题的人。
我目前正在使用文本框来过滤一些条目。我在文本框 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 或追加,则会出现违规异常。
虽然这不是一个完整的答案,但我希望它能帮助任何设法找到这个问题的人。