从视图绑定到 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 之外的值。
想到另外两种可能性:
将 WhenAnyValue
与 toProperty
放在一起,然后将视图控件绑定到 ViewModel属性
将您服务中的状态更改公开为 IObservable,而不是布尔值,您可以在视图中订阅该 Observable。
我正在使用 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 之外的值。
想到另外两种可能性:
将
WhenAnyValue
与toProperty
放在一起,然后将视图控件绑定到 ViewModel属性将您服务中的状态更改公开为 IObservable,而不是布尔值,您可以在视图中订阅该 Observable。