RX 自动完成框

发布于 2024-10-27 16:03:42 字数 175 浏览 3 评论 0原文

我正在尝试使用 RX 和 WPF 构建过滤器控件。 所以我有一个文本框和一个列表框。 启动时,列表框有 100 个联系人姓名,用户可以输入姓名来过滤列表。

问题是我如何构建文本流(关键输入)然后发布。这应该是时间敏感的,所以我想只有在 750 毫秒后,如果尚未检测到按键输入,则可以执行过滤器。

谢谢

I'm trying to build an filter control using RX and WPF.
So I have a textbox and a listbox.
On start up the listbox has 100 contact names and the user can type in a name to filter the list.

Question is how can I build up an text stream (key inputs) and then publish. This should be Time sensitive so I guess only after 750milliseconds if a key input hasnt been detected then the filter may be performed.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

椒妓 2024-11-03 16:03:42

基本轮廓如下所示 将

  1. 文本框按键事件转换为击键的 IO 节流
  2. ,以便我们在用户实际键入时不会进行搜索 进行
  3. 搜索 将
  4. 搜索结果放置到列表框中

这是一些伪代码 -

 var keysIO =   Observable.FromEvent<KeyDownEventHandler, RoutedEventArgs>(
                                    h => new KeyDownEventHandler(h),
                                    h => btn.KeyDown += h,
                                    h => btn.KeyDown -= h));

 var searchResults = keysIO.Throttle(TimeSpan.FromSeconds(0.750),Scheduler.Dispatcher);

 searchResults.Subscribe(sr => {  lb.Clear(); lb.AddRange(sr); });

@Andy,Throttle 不会每 750 毫秒启动一次搜索,只有在用户停止输入 750 毫秒后才会启动。在 LinqPad 中尝试一下。

   Observable.Interval(TimeSpan.FromMilliseconds(10))
   .Do(ii =>  "keystroke".Dump())
   .Take(10)
   .Throttle(TimeSpan.FromSeconds(0.750))
   .Select(ttl => "search")

The basic outline would looks like so

  1. textbox keydown event converted to an IO
  2. throttling of the keystrokes, so that we don't search while the user is actually typing
  3. Do the search
  4. Place the the search results onto the list box

Here's some pseudo-code -

 var keysIO =   Observable.FromEvent<KeyDownEventHandler, RoutedEventArgs>(
                                    h => new KeyDownEventHandler(h),
                                    h => btn.KeyDown += h,
                                    h => btn.KeyDown -= h));

 var searchResults = keysIO.Throttle(TimeSpan.FromSeconds(0.750),Scheduler.Dispatcher);

 searchResults.Subscribe(sr => {  lb.Clear(); lb.AddRange(sr); });

@Andy, Throttle won't kick off a search every 750ms, only after the user has stopped typing for 750ms. Try this in LinqPad.

   Observable.Interval(TimeSpan.FromMilliseconds(10))
   .Do(ii =>  "keystroke".Dump())
   .Take(10)
   .Throttle(TimeSpan.FromSeconds(0.750))
   .Select(ttl => "search")
九歌凝 2024-11-03 16:03:42

斯科特·韦恩斯坦的建议是正确的。

此外,由于您想要影响 Gui 控件,因此必须确保在订阅之前 ObserveOn the Dispatcher 或使用调度程序,以使您返回到调度程序线程。

这对我有用:

 Observable.FromEvent<TextChangedEventArgs>(TextBox, "TextChanged")
                .Throttle(TimeSpan.FromSeconds(0.75), Scheduler.Dispatcher)
                .Select(obs => TextBox.Text)
                .Subscribe(TextChangedTo);

现在在 TextChangedTo(text) 方法中,您可以使用联系人姓名填充列表。

What Scott Weinstein is suggesting is correct.

Additionally, since you want to affect a Gui control, you have to make sure to either ObserveOn the Dispatcher or use the scheduler somewhere before you subscribe, to get you back to the dispatcher thread.

This worked for me:

 Observable.FromEvent<TextChangedEventArgs>(TextBox, "TextChanged")
                .Throttle(TimeSpan.FromSeconds(0.75), Scheduler.Dispatcher)
                .Select(obs => TextBox.Text)
                .Subscribe(TextChangedTo);

Now in the TextChangedTo(text) method you would populate your list with contact names.

怎会甘心 2024-11-03 16:03:42

在新版本的 Rx 上,Scheduler.Dispatcher 已经消失,并且 FromEvent 似乎不能很好地与 WPF 配合使用,因此,对于今天需要解决方案的任何人,这里有一个名为 FilterText 的文本框的工作解决方案:

Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
    h => this.FilterText.TextChanged += h,
    h => this.FilterText.TextChanged -= h)
    .Throttle(new TimeSpan(0, 0, 0, 0, 750))
    .ObserveOnDispatcher()
    .Subscribe(t => DoFiltering(this.FilterText.Text));

On new versions of Rx the Scheduler.Dispatcher has disappeared and FromEvent seems that does not work well with WPF, so, for anyone that needs a solution today here you have a working solution for a textbox named FilterText:

Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
    h => this.FilterText.TextChanged += h,
    h => this.FilterText.TextChanged -= h)
    .Throttle(new TimeSpan(0, 0, 0, 0, 750))
    .ObserveOnDispatcher()
    .Subscribe(t => DoFiltering(this.FilterText.Text));
我爱人 2024-11-03 16:03:42

这里有一个完整的示例,带有幻灯片和源代码

There's a full example here, with slides and source code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文