RX AutoCompleteBox - PullRequest
       2

RX AutoCompleteBox

4 голосов
/ 26 марта 2011

Я пытаюсь построить фильтр управления с использованием RX и WPF.Итак, у меня есть текстовое поле и список.При запуске список имеет 100 имен контактов, и пользователь может ввести имя, чтобы отфильтровать список.

Вопрос в том, как создать поток текста (ключевые входы), а затем опубликовать.Это должно быть чувствительно ко времени, поэтому, я думаю, только через 750 миллисекунд, если ввод ключа не обнаружен, тогда фильтр может быть выполнен.

Спасибо

Ответы [ 4 ]

7 голосов
/ 26 марта 2011

Базовая схема выглядит так

  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")
2 голосов
/ 26 марта 2011

То, что предлагает Скотт Вайнштейн, верно.

Кроме того, поскольку вы хотите повлиять на элемент управления Gui, вы должны обязательно либо ObserveOn the Dispatcher, либо использовать планировщик где-нибудь перед подпиской, чтобы вернуть вас в поток диспетчера.* Это сработало для меня:

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

Теперь в методе TextChangedTo(text) вы должны заполнить свой список именами контактов.

1 голос
/ 15 апреля 2013

В новых версиях 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));
0 голосов
/ 26 марта 2011

Полный пример здесь , со слайдами и исходным кодом

...