I would like to implement a TextBox where, as you type, results appear instantly in another ListBox. I've been looking for examples with Reactive Extensions (Rx), and all of the ones I found use Observable.FromEventPattern()
together with the TextBox's TextChanged
event:
- Implementing simple instant search with Rx (Reactive Extensions) (this is actually WinForms)
- An Rx-Enabled WPF AutoComplete TextBox - Part 1/2
- Search on TextChanged with Reactive Extensions
I'm using WPF with MVVM so I can't exactly access the TextBox or its events directly.
I've also stumbled upon this answer which shows how Observable.FromEventPattern()
can be used in an MVVM setting, but I was hoping for something better than capturing every single PropertyChanged
event.
What is a good alternative to Observable.FromEventPattern()
that can work nicely with WPF/MVVM?
You can use a behavior to get this working. A great example is the UpdateBindingOnTextChanged behavior of Catel. It can be used like this:
This will create a 500ms delay between the change and the actual update.
This is the kind of approach that I would use in this instance:
The
executeSearch
code has the following signature:Func<string, IObservable<string>>
.The important part with this query is the final
Switch
statement. It turns anIObservable<IObservable<string>>
into aIObservable<string>
by only returning the results of the latest observable.The calls to
.ObserveOnDispatcher()
&.ObserveOn(Scheduler.Default)
ensure that different parts of the observable query happen on the correct threads.Got this working with ReactiveUI.
The solution is based on a blog post at ReactiveUI, but the code there is a little bit out of date. I am hosting the solution on BitBucket for ease of access. It uses ReactiveUI 5.5.1.
This is the ViewModel from that solution.
SearchText
is bound to aTextBox
in the View where the user types his query, whileSearchResults
is bound to aListBox
displaying the results.