我们正在使用带有ReactiveUI的Xamarin.Forms构建跨平台应用。 应用程序结构基于以下示例:
https://github.com/GiusepeCasagrande/reactive-dev-days-lab
Android版本按预期工作,但是,在iOS模拟器上,当您运行命令" SyncSpeakers"时,命令成功执行,视图闪烁但列表未填充。
任何人都可以理解为什么会这样吗? 我应该放弃使用xammvvm进行路由并切换到其他地方吗?
发言人的ViewModel代码如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using DevDaysSpeakers.Model;
using DevDaysSpeakers.Services;
using ReactiveUI;
using Xamarin.Forms;
using Xamvvm;
namespace DevDaysSpeakers.ViewModel
{
public class SpeakersViewModel: BasePageModelRxUI
{
public ReactiveList<Speaker> Speakers { get; } = new ReactiveList<Speaker>();
Speaker speaker;
public Speaker Speaker
{
get { return speaker; }
set { this.RaiseAndSetIfChanged(ref speaker, value); }
}
public ReactiveCommand<Unit, IEnumerable<Speaker>> GetSpeakers { get; }
public ReactiveCommand GoToDetails { get; }
readonly ObservableAsPropertyHelper<bool> busy;
public bool IsBusy => busy.Value;
public SpeakersViewModel()
: this(null)
{
}
public SpeakersViewModel(AzureService azureService = null)
{
var service = azureService ?? DependencyService.Get<AzureService>();
GetSpeakers = ReactiveCommand.CreateFromTask(_ => service.GetSpeakers());
GetSpeakers
.ObserveOn(RxApp.MainThreadScheduler)
.SubscribeOn(RxApp.MainThreadScheduler)
.Subscribe(speakers =>
{
Speakers.Clear();
Speakers.AddRange(speakers);
});
GetSpeakers.IsExecuting
.ToProperty(this, vm => vm.IsBusy, out busy);
GetSpeakers.ThrownExceptions
.Subscribe(error => Application.Current.MainPage.DisplayAlert("Error!", error.Message, "OK"));
// go to details page when Speaker is set
this.WhenAnyValue(vm => vm.Speaker)
.Where(speaker => speaker != null)
.Subscribe(speaker => this.PushPageFromCacheAsync<DetailsViewModel>(vm => vm.Speaker = speaker));
this.ThrownExceptions
.Subscribe(ex =>
{
Debug.WriteLine(ex.Message);
});
}
}
}
视图的XAML:
<?xml version="1.0" encoding="utf-8"?>
<reactive:ReactiveContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:reactive="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
xmlns:xamvvm="clr-namespace:Xamvvm;assembly=Xamvvm.Forms.RxUI"
xmlns:local="clr-namespace:DevDaysSpeakers.ViewModel;assembly=DevDaysSpeakers"
x:Class="DevDaysSpeakers.View.SpeakersPage"
x:TypeArguments="local:SpeakersViewModel"
Title="Speakers"
x:Name="ThePage">
<reactive:ReactiveContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" />
</reactive:ReactiveContentPage.Padding>
<reactive:ReactiveContentPage.Content>
<StackLayout Spacing="0">
<Button x:Name="SyncSpeakers" Text="Sync Speakers" />
<ActivityIndicator x:Name="IsBusy" />
<ListView x:Name="ListViewSpeakers">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Name}" Detail="{Binding Title}" ImageSource="{Binding Avatar}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</reactive:ReactiveContentPage.Content>
</reactive:ReactiveContentPage>
视图后面的代码
using System.Reactive.Disposables;
using DevDaysSpeakers.ViewModel;
using ReactiveUI;
using Xamvvm;
namespace DevDaysSpeakers.View
{
public partial class SpeakersPage
: IBasePageRxUI<SpeakersViewModel>
{
public SpeakersPage()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
this.OneWayBind(ViewModel, x => x.Speakers, x => x.ListViewSpeakers.ItemsSource).DisposeWith(disposables);
this.OneWayBind(ViewModel, x => x.GetSpeakers, x => x.SyncSpeakers.Command).DisposeWith(disposables);
this.OneWayBind(ViewModel, x => x.IsBusy, x => x.IsBusy.IsVisible).DisposeWith(disposables);
this.OneWayBind(ViewModel, x => x.IsBusy, x => x.IsBusy.IsEnabled).DisposeWith(disposables);
this.Bind(ViewModel, x => x.Speaker, x => x.ListViewSpeakers.SelectedItem).DisposeWith(disposables);
});
}
}
}
适用于iOS的Project.json
{
"supports": {},
"dependencies": {
"Microsoft.Azure.Mobile.Client.SQLiteStore": "3.1.0",
"Microsoft.Bcl.Build": "1.0.21",
"reactiveui-events-xamforms": "7.1.0",
"reactiveui-xamforms": "7.1.0",
"SQLitePCLRaw.bundle_e_sqlite3": "1.1.2",
"Xam.Plugins.TextToSpeech": "2.0.0",
"Xamarin.Forms": "2.3.3.180",
"Xamvvm.Forms.RxUI": "1.0.2"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": {}
}
}
答案 0 :(得分:1)
这是一个Xamarin.Forms错误。您可以在此处查看讨论https://github.com/reactiveui/ReactiveUI/issues/806
这就是错误本身:https://bugzilla.xamarin.com/show_bug.cgi?id=31415
在第一个链接中,您可以找到一些解决方法,一个非常简单的方法就是更改ObservableCollection的ReactiveList。