RX AutoCompleteBox

I am trying to create a filter control using RX and WPF. Therefore, I have a text box and a list. When launched, the list contains 100 contact names, and the user can enter a name to filter the list.

The question is how can I create a text stream (key inputs) and then publish. This should be time sensitive, so, I think, only after 750 milliseconds, if key input has not been detected, the filter can be executed.

thanks

+4
source share
4 answers

The main outline will look like this

  • keydown text event converted to IO
  • throttling of keystrokes so that we do not search while the user types.
  • Do a search
  • Put your search results in the list box.

Here is 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 will not start the search every 750 ms, only after the user stops printing for 750 ms. Try this on LinqPad.

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

What Scott Weinstein offers is right.

In addition, since you want to influence the Gui control, you must make sure that either ObserveOn Dispatcher or use the scheduler somewhere before subscribing to return you to the dispatcher stream.

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 must populate the list with contact names.

+2
source

In newer versions of Rx, Scheduler.Dispatcher has disappeared, and FromEvent seems to work poorly with WPF, so for those who need a solution today, you have a working solution for a text field called 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)); 
+1
source

Here is a complete example here , with slides and source code

0
source

Source: https://habr.com/ru/post/1345289/


All Articles