我正在使用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交互的控件)。
答案 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之外的值。
另外还有两种可能性:
将WhenAnyValue
与toProperty
一起放入ViewModel中,然后将您的视图控件绑定到ViewModel中的该属性
将服务中的状态更改公开为bool,但作为IObservable,您可以在视图中订阅该Observable。