从视图绑定到 ReactiveUI 服务

Binding to a ReactiveUI Service from a View

我正在使用 RxUI 7 并努力将 RxUI 属性 从派生自 ReactiveObject 的常量服务(向 Splat 注册)绑定到我的 Xamarin Forms 视图。

我在应用程序初始化时注册了如下服务:

Locator.CurrentMutable.RegisterConstant(new CurrentAudioService(), typeof(ICurrentAudioService));

然后我按如下方式实现了 CurrentAudioService:

public class CurrentAudioService : ReactiveObject, ICurrentAudioService
{
    private bool _isPlaying;

    public bool IsPlaying
    {
        get { return _isPlaying; }
        set { this.RaiseAndSetIfChanged(ref _isPlaying, value); }
    }
}

ICurrentAudioService 正确定义 IsPlaying。

在我看来,我尝试了以下方法:

private readonly ICurrentAudioService _currentAudioService;

public PlayerView() : base()
{
    InitializeComponent();

    // Resolve the view
    _currentAudioService = _currentAudioService ?? Locator.Current.GetService<ICurrentAudioService>();

    this.WhenActivated(disposables =>
    {
        this.OneWayBind(_currentAudioService, cas => cas.IsPlaying, c => c.Player.IsVisible)
            .DisposeWith(disposables);
    }
}

如果我将 WhenActivated 中的代码更改为:

_currentAudioService.WhenAnyValue(x => x.IsPlaying)
    .Subscribe((isPlaying) =>
    {
        Player.IsVisible = isPlaying;
    })
    .DisposeWith(disposables);

一切正常。为什么当我尝试绑定到该服务时会失败,有什么方法可以让它工作吗?

澄清一下,currentAudioService 作为服务而不是视图模型实现的原因是因为 currentAudioService 将在应用程序中的所有视图之间共享(每个视图都有自己的控件与 currentAudioService 交互) ).

尝试改变你的方法。如果您有多个具有相同功能的 ViewModel,而不是使用服务,只需创建一个 ViewModelBase,如下所示:

public class PlayerBaseViewModel : ReactiveObject
{
   private bool _isPlaying;
   public bool IsPlaying
   {
      get { return _isPlaying; }
      set { this.RaiseAndSetIfChanged(ref _isPlaying, value); }
   }
}

然后您可以在共享相同功能的 ViewModel 中简单地继承它。另外不要忘记,在 ReactiveUI 中,您需要在视图中实现接口 IViewFor<YourViewModel>,以便将 ViewModel 与相应的视图相关联。

如果您使用的是 Nuget 包 reactiveui-xamforms,而不是实现 IViewFor<YourViewModel>,您的视图可以继承自 ReactiveContentPage<SearchViewModel>,它正在为您实现 IViewFor

希望对您有所帮助。

此致

问题是使用 Bind 依赖于视图的 ViewModel 属性,并且据我所知只能绑定到该 VM 内的属性。

恕我直言 WhenAnyValue 是正确的方法,因为您想观察 ViewModel 之外的值。

想到另外两种可能性:

  1. WhenAnyValuetoProperty 放在一起,然后将视图控件绑定到 ViewModel属性

  2. 将您服务中的状态更改公开为 IObservable,而不是布尔值,您可以在视图中订阅该 Observable。