WPF ComboBox 延迟筛选

3
考虑以下情况:有一个 ComboBox 和一个筛选 TextBox,当用户在文本框中输入文本时,ComboBox 的项源会使用筛选文本进行更新。一切都运作正常,但是过滤器在每个输入的字母上都会发生。我想在过滤器应用之前添加延迟(当用户正在输入时不应用过滤器)。最简单的方法是什么?

1
我现在记不起具体的计时器类了,所以暂不写回答。但是在你的视图模型(如果你正在使用MVVM),你可以让数据更新启动计时器,而不是直接应用到组合框中。确保设置它只触发一次,并在每次输入数据时重置。将其设置为500毫秒。然后它只会在用户停止键入500ms后更新。我曾在自定义文件系统目录选择器自动完成文本框控件(类似于运行提示)上使用过这种方法。它效果很好且容易使其无bug。 - Merlyn Morgan-Graham
@Merlyn 谢谢,我也会尝试这种方法。 - Petr Abdulin
我相信这与被接受的答案差不多。希望它对你有用。干杯! - Merlyn Morgan-Graham
@Merlyn,实际上在测试两种方法之后,我发现您的方法更方便,因为它不需要“TimeSinceType”变量和在“*_TextChanged”方法中进行额外检查。 - Petr Abdulin
哦,我明白了区别。我会在今天晚些时候将其添加为答案。有点作弊,因为他的答案让我想起要使用计时器类 ;) - Merlyn Morgan-Graham
如果您正在使用MVVM,请参见我的下面的回答,而不是执行此处讨论的操作。不需要计时器 - 只需在绑定上延迟即可。 - Josh
2个回答

7

最常用的做法是引入一个计时器,每当用户输入一个新字符时,您的时间跨度就会被重置,但如果超过x秒,则执行代码。

记得要异步执行,这样如果用户在执行搜索时再次开始输入,您可以取消异步调用,因为该信息现在已过时。

如果您正在使用视图模型,请将textbox1_TextChanged更改为相应的属性设置器。

private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (!tmr.Enabled)
        {
            tmr.Enabled = true;
            tmr.Start();
        }


        TimeSinceType = DateTime.Now;

    }

public DateTime TimeSinceType { get; set; }

protected void Load()
{
      tmr = new Timer();
      tmr.Interval = 200;
      tmr.Elapsed += new ElapsedEventHandler(tmr_Elapsed);
}

void tmr_Elapsed(object sender, ElapsedEventArgs e)
{
    if ((DateTime.Now - TimeSinceType).Seconds > .5)
    {
        Dispatcher.BeginInvoke((Action)delegate()
        {
            //LoadData();
            tmr.Stop();
        });
    }
}

你需要调度程序来调用它吗?如果没有它,您会遇到线程错误(UI线程)吗? - Merlyn Morgan-Graham
如果你要在UI线程上更新某些内容,你可以尝试这个方法,但你会发现它会抛出一个InvalidOperationException异常:调用线程无法访问此对象,因为另一个线程拥有它。 - TBohnen.jnr
在计算经过的时间差时,应该使用.TotalSeconds而不是.Seconds。如果您不了解这两者之间的区别,那么您可能会引入一些微妙的错误,这些错误可能非常难以追踪。 - Bent Tranberg
TimeSinceType 在计时器启动后在 textBox1_TextChanged 中设置。存在风险,可能在计时器处理程序使用之前尚未设置。 - Bent Tranberg
在计时器的处理程序中,使用了DateTime.Now。为了提高准确性并减少资源的使用,最好使用e.SignalTime。 - Bent Tranberg
显示剩余2条评论

1

现在可以通过直接在绑定上设置延迟来更轻松地完成此操作:

<ComboBox Text={Binding MyBinding, Delay=200} />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接