【问题标题】:Communicating between view and view model using ReactiveUI.NET使用 ReactiveUI.NET 在视图和视图模型之间进行通信
【发布时间】:2013-12-19 12:26:09
【问题描述】:

我对反应式 UI 还很陌生。我在我的应用程序中广泛使用它进行异步编程等。

我有一个问题。我的 ViewModel 中有一个异步方法,它“等待”任务完成。完成此任务后,我想通知我的视图(用户控件),以便它可以动态添加更多内容/用户控件,例如 DockPanel。

使用 ReactiveUI 或 RX 执行此操作的最佳方法是什么?我可以使用 C# 事件机制等,但我想继续 RX 路径。当异步方法“完成”(即从等待返回)时,我在我的 VM 中设置了一个 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

任何指导将不胜感激,非常感谢。

【问题讨论】:

    标签: c# mvvm system.reactive reactiveui


    【解决方案1】:

    您的想法基本正确,只需要在语法上做一些工作:

    this.WhenAnyValue(x => x.ViewModel.DataLoaded)
        .Where(x => x == true)
        .Subscribe(_ => MyViewHandler());
    

    【讨论】:

    • 感谢 Paul 的及时回复。也感谢 jnovo。我猜他给了我使用 Rx 或 TPL 做事的替代方法,但如果可能的话,我宁愿使用 ReactiveUI 方式。我想我从我的视图(派生自用户控件)中尝试了类似 WhenAnyValue 的东西,但编译器不喜欢它。那么上面的代码,会出现在视图中吗?
    • 是的,它会出现在视图中——如果编译器不喜欢它,也许你错过了一个“使用”语句?或者您使用的是旧版本的 RxUI?
    • 嗨,保罗,我确信我已经得到了“使用”语句来引用正确的命名空间。我认为我使用的是 4.4.6 版。
    • 啊。 v4 没有WhenAnyValue,改用WhenAny(x => x.ViewModel.DataLoaded, x => x.Value)
    【解决方案2】:

    您的示例代码的问题在于,正如编译器所说,您没有将有效的 IObserver 实现传递给 Subscribe 方法。您实际上传递了一个Func<boolean, Task>,它期望一个Action<boolean> 实现IObserver.OnNext

    我没有尝试过 ReactiveUI,但我认为你可以完成,但你打算使用 Task ContinuationIObserver.OnCompleted。几个想法是:

    • 使用任务继续,一旦您提到的任务完成,您将启动另一个任务。您可以通过将.ContinueWith 调用附加到您的任务来执行此操作。请记住,修改 UI 的延续任务中的代码必须从延续任务分派到 UI 线程(使用Dispatcher 或将正确的TaskScheduler 传递给ContinueWith)。

      李> 1234563 .

    【讨论】:

    • 我不想太苛刻,但如果你没有尝试过 ReactiveUI,你为什么要回答一个关于它的问题?这个答案几乎完全不正确。
    • @PaulBetts 没有冒犯,从我的角度来看,他询问了 ReactiveUI 或 RX,所以我试图帮助 RX 并提供有关 TPL 的提示。如果它不适用,我很乐意将其删除。现在,如果您指出不正确的地方,我可以尝试修复它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2020-01-09
    • 2011-09-06
    • 2012-06-28
    • 2016-01-05
    相关资源
    最近更新 更多