c# - 使用 ObservableAsPropertyHelper 激活/停用

标签 c# dispose reactiveui

激活/停用与 ObservableAsPropertyHelper 的正确用法是什么?给定反射(reflect)长期(热)可观察对象的 View 和 View 模型,订阅将需要在卸载 View 和 View 模型时处理。但是,建议只读的 ObservableAsPropertyHelper 在 View 模型的构造函数中分配,并且不能成为激活/停用生命周期的一部分。处理此类情况的正确方法是什么?

public interface ILongLivedObject
{
    IObservable<bool> Status { get; }
}


public class TestViewModel : ReactiveObject
{
    private readonly ObservableAsPropertyHelper<bool> _status;
    public bool Status => _status.Value;

    public TestViewModel(ILongLivedObject obj)
    {
         _status = obj.Status.ToProperty(this, vm => vm.Status); //how is the subscription disposed?
    }


}

这也让我在尝试添加依赖于此状态的命令时陷入困境。在我的应用程序中,一个常见的用例是让一些硬件处于某种特定状态(例如 IsOpen),并在它为真时允许命令。 在不知道更好的情况下,这就是我正在尝试做的事情:


public class TestViewModel : ReactiveObject
{
    private readonly ObservableAsPropertyHelper<bool> _status;
    public bool Status => _status.Value;

    public ReactiveCommand<Unit, Unit> DoStuff {get;}

    public TestViewModel(ILongLivedObject obj)
    {
         _status = obj.Status.ToProperty(this, vm => vm.Status); //how is the subscription disposed?
         DoStuff = ReactiveCommand.CreateFromTask(....., this.WhenAnyValue(this, x => x.Status);
    }


}

如果我尝试将 _status 创建移动到 this.WhenActivated 中,应用程序将崩溃,因为命令试图在它创建之前获取状态值。我应该在激活期间(重新)创建命令吗?这似乎是错误的,而且成本很高?

到目前为止,拥有一个带有 protected setter 的常规 Status 属性并在 this.WhenActivated 中进行常规订阅似乎更好 - 但这是手册告诉要避免的“只读”属性。

最佳答案

所以在 Reactive 编程中需要注意一件事,处置通常意味着“取消订阅”。

您通常不需要取消订阅,因为垃圾收集器会为您处理,为您提供仅生成可观察对象的 ObservableAsPropertyHelper(缩写为 OAPH)来自当前的 ViewModel。

然而,在您的情况下,您的可观察对象/对象与当前 ViewModel 外部的对象相关。 OAPH 本身是一个 Disposable 对象。

因此您可以使用 ISupportsActivation(很快将替换 IActivableViewModel)并将您的 OAPH 传递到它的 Disposable 属性中。

public class TestViewModel : ReactiveObject, ISupportsActivation
{
    private readonly ObservableAsPropertyHelper<bool> _status;
    public bool Status => _status.Value;
    public ViewModelActivator Activator { get; } = new ViewModelActivator();

    public TestViewModel(ILongLivedObject obj)
    {
         _status = obj.Status.ToProperty(this, vm => vm.Status);
         this.WhenActivated(disposables =>
         {
             disposables(_status);
         }
    }
}

传递到 WhenActivated lambda 的 disposables 参数是一个采用 IDisposable 的 Func

在 View 中,确保派生自 IActivatable(即将重命名为 IActivatableView)并在 View 的构造函数中使用 WhenActivated。

关于c# - 使用 ObservableAsPropertyHelper 激活/停用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56033281/

相关文章:

c# - Razor 语法问题

WCF ChannelFactory 和 channel - 缓存、重用、关闭和恢复

c# - 处理 File.Open 或 StreamContent

c# - 使用 ReactiveUI 绑定(bind) TextBox 并保持货币格式

c# - 使用正则表达式过滤 IObservable<string> 并返回匹配值

c# - 如何在C#中检查对象是否可序列化

C# 套接字和 ClearCase 动态 View 问题

c# - 我的控件没有被正确处理?

c# - WPF - ReactiveUI InvokeCommand 不工作

c# - 什么会导致 Application_Error 不被调用?