从视图绑定到ReactiveUI服务

时间:2017-03-04 13:15:17

标签: xamarin.forms reactiveui

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

我在App初始化时注册了如下服务:

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交互的控件)。

2 个答案:

答案 0 :(得分:1)

尝试改变你的方法。如果你有几个具有相同功能的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与相应的View相关联。

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

希望得到这个帮助。

此致

答案 1 :(得分:0)

问题是使用Bind依赖于View的ViewModel属性,并且只能按照我的理解绑定到该VM内的Properties。

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

另外还有两种可能性:

  1. WhenAnyValuetoProperty一起放入ViewModel中,然后将您的视图控件绑定到ViewModel中的该属性

  2. 将服务中的状态更改公开为bool,但作为IObservable,您可以在视图中订阅该Observable。