Связь между представлением и моделью представления с использованием ReactiveUI.NET

Я довольно новичок в реактивном пользовательском интерфейсе. Я широко использую его в своем приложении для асинхронного программирования и т. д.

У меня есть вопрос. У меня есть метод в моей ViewModel, который является асинхронным и который «ожидает» завершения задачи. По завершении этой задачи я хотел бы уведомить свое представление (UserControl), чтобы он мог динамически добавлять еще контент/UserControls, например, DockPanel.

Как лучше всего это сделать с помощью ReactiveUI или RX? Я мог бы использовать механизм событий C# и т. д., но я хочу продолжить путь RX. Я устанавливаю свойство boolena в своей виртуальной машине, когда асинхронный метод «завершен» (т.е. возвращается из ожидания).

Затем я хочу наблюдать за этим логическим свойством (определенным в моей виртуальной машине) в моем «представлении»... поэтому я могу прикрепить обработчик в своем «представлении», который будет динамически создавать некоторые пользовательские элементы управления, например

this.viewModel.ObservableForProperty(x => x.DataLoaded)
              .Subscribe(async _ => await this.MyViewHandler()); 
// this does not compile as the delegate is not IObserver type in my view it says

Любое руководство будет высоко оценено, большое спасибо.


person nDev    schedule 19.12.2013    source источник


Ответы (2)


У вас в основном есть правильная идея, просто нужно немного поработать над синтаксисом:

this.WhenAnyValue(x => x.ViewModel.DataLoaded)
    .Where(x => x == true)
    .Subscribe(_ => MyViewHandler());
person Ana Betts    schedule 20.12.2013
comment
Спасибо Павел за очень быстрый ответ. Спасибо за jnovo тоже. Я предполагаю, что он давал мне альтернативные способы делать вещи, используя Rx или TPL, но я предпочитаю использовать ReactiveUI, если это возможно. Я думаю, что попробовал что-то вроде WhenAnyValue из моего представления (которое является производным от Usercontrol), но компилятору это не понравилось. поэтому приведенный выше код будет отображаться в представлении? - person nDev; 20.12.2013
comment
Да, это будет отображаться в представлении - если компилятору это не нравится, может быть, вам не хватает оператора «использование»? Или вы используете более старую версию RxUI? - person Ana Betts; 20.12.2013
comment
Привет, Пол, я уверен, что у меня есть оператор using для ссылки на правильное пространство имен. Я использую версию 4.4.6, я думаю. - person nDev; 21.12.2013
comment
Ах. v4 не имеет WhenAnyValue, вместо этого используйте WhenAny(x => x.ViewModel.DataLoaded, x => x.Value) - person Ana Betts; 21.12.2013

Проблема с вашим примером кода заключается в том, что, как говорит компилятор, вы не передаете допустимую реализацию IObserver методу Subscribe. На самом деле вы передаете Func<boolean, Task> там, где ожидается Action<boolean>, реализующий IObserver.OnNext.

Я не пробовал ReactiveUI, но я думаю, что вы можете выполнить, но вы намерены выполнить либо Task Продолжение или с помощью IObserver.OnCompleted. Пара идей:

  • Используя «Продолжение задачи», вы запустите другую задачу после завершения той, о которой вы упомянули. Вы можете сделать это, добавив к своей задаче вызов .ContinueWith. Имейте в виду, что код из задачи продолжения, изменяющий пользовательский интерфейс, должен быть отправлен в поток пользовательского интерфейса из задачи продолжения (либо с помощью Dispatcher, либо путем передачи правильного TaskScheduler в ContinueWith).

  • С помощью RX вы можете создать последовательность для своей задачи с помощью правильного Observable.Create фабричного метода или просто с помощью Task.ToObservable методов расширения, затем подпишитесь на него и делайте с обработчиком OnCompleted все, что хотите.

person jnovo    schedule 19.12.2013
comment
Ненавижу быть резким, но если вы не пробовали ReactiveUI, зачем вам отвечать на вопрос об этом? Этот ответ почти полностью неверен. - person Ana Betts; 20.12.2013
comment
@PaulBets без обид, с моей точки зрения, он спросил либо о ReactiveUI, либо о RX, поэтому я попытался помочь с RX, а также дал намек на TPL. Я с удовольствием удалю это, если это не применимо. Теперь, если вы укажете мне, что неправильно, я могу попытаться это исправить. - person jnovo; 20.12.2013