Reactive Extensions Instant Search for WPF/MVVM

后端 未结 3 1825
误落风尘
误落风尘 2020-12-19 18:20

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 o

3条回答
  •  天涯浪人
    2020-12-19 18:45

    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 a TextBox in the View where the user types his query, while SearchResults is bound to a ListBox displaying the results.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using System.ComponentModel;
    using System.Reactive.Linq;
    using System.Windows.Input;
    
    using ReactiveUI;
    
    namespace ReactiveExtensionsSearch
    {
        public class MainWindowViewModel : ReactiveObject
        {
            private string[] _repository = new string[]
                { "Mario", "Maria", "Gigi", "Jack", "James", "Jeremy" };
            private ObservableAsPropertyHelper> _searchResults;
            private string _searchText;
            private ICommand _executeSearchCommand;
    
            public string SearchText
            {
                get
                {
                    return _searchText;
                }
                set
                {
                    this.RaiseAndSetIfChanged(ref _searchText, value);
                }
            }
    
            public ObservableCollection SearchResults
            {
                get
                {
                    return _searchResults.Value;
                }
            }
    
            public MainWindowViewModel()
            {
                var executeSearchCommand = new ReactiveCommand();
                var results = executeSearchCommand.RegisterAsyncFunction(s => { return ExecuteSearch(s as string); });
                _executeSearchCommand = executeSearchCommand;
    
                this.ObservableForProperty("SearchText")
                    .Throttle(TimeSpan.FromMilliseconds(800))
                    .Select(x => x.Value)
                    .DistinctUntilChanged()
                    .Where(x => !string.IsNullOrWhiteSpace(x))
                    .Subscribe(_executeSearchCommand.Execute);
    
               _searchResults = new ObservableAsPropertyHelper>(results, _ => raisePropertyChanged("SearchResults"));
            }
    
            private ObservableCollection ExecuteSearch(string searchText)
            {
                var q = from s in _repository where s.ToLower().StartsWith(searchText.ToLower()) select s;
                var results = new ObservableCollection(q);
                return results;
            }
        }
    }
    

提交回复
热议问题