我有一个以Xamarin形式设置的MVVM样式应用程序,我通过ViewModel第一种方法显示我的登录页面,该方法本身托管在NavigationPage中。
我注入了一个INavigationService实例,它建立了正确的Navigation属性,如下所示:
var navigationController = Application.Current.MainPage as NavigationPage;
if (navigationController != null)
return navigationController.Navigation;
然后让我可以访问PushAsync方法,如下所示:
public async Task PushAsync(INavigationPageModel page)
{
var view = _viewFactory.CreatePage(page);
await Navigation.PushAsync(view);
}
现在,如果我在Command中使用此方法(例如),我发现我的视图被正确地推送到导航堆栈并且是可见的。但是,我使用Rx来观察连接的'通过BehaviourSubject在我的应用程序上的状态似乎给我带来了一些麻烦。
我没有收到任何错误,但我发现视图本身出现被推入堆栈但对我来说是不可见的(我可以在堆栈中看到它调试器)。我只能假设这与UI线程有某种关系,但我不确定。
我的RX订阅经历了几次迭代,因为看起来我需要支持异步方法的调用。目前它看起来像这样:
_application.ConnectionManager.State
.Where(s => s == ConnectionState.Connected)
.SelectMany(l => Observable.FromAsync(ChangePageAsync))
.SubscribeOn(Scheduler.UiScheduler)
.Subscribe();
我的更改页面方法如下所示:
private Task ChangePageAsync()
{
var viewModel = _viewModelFactory.CreateModel<DashboardPageViewModel>();
return Navigation.PushAsync(viewModel);
}
为了完整性,我在iOS应用程序的AppDelegate中捕获UI调度程序,如下所示:
new SynchronizationContextScheduler(SynchronizationContext.Current);
正如我所说,我没有错误,但它只是没有通过Rx异步动作向我显示新页面。有任何想法吗?它让我疯狂。
答案 0 :(得分:1)
哦,对不起,还没有完全阅读代码。您需要使用ObserveOn
而不是SubscribeOn
并将其放在SelectMany
之前。将其更改为:
_application.ConnectionManager.State
.Where(s => s == ConnectionState.Connected)
.ObserveOn(Scheduler.UiScheduler)
.SelectMany(l => Observable.FromAsync(ChangePageAsync))
.Subscribe();
这确保在尝试更改页面之前,它位于UI线程上。 SubscribeOn用于确保在指定的调度程序上执行订阅的脚手架(通常在订阅阻止时使用)。