Xamarin.ios Xamarin.Forms+;反应性ui+;Xamvvm视图仅在iOS上不更新

Xamarin.ios Xamarin.Forms+;反应性ui+;Xamvvm视图仅在iOS上不更新,xamarin.ios,xamarin.forms,reactiveui,Xamarin.ios,Xamarin.forms,Reactiveui,我们正在使用Xamarin.Forms和ReactiveUI构建一个跨平台的应用程序。 应用程序结构基于以下示例: Android版本的工作原理与预期一致,但是,在iOS模拟器上,当您运行命令“SyncSpeakers”时,命令成功执行,视图闪烁,但列表未填充 有人能理解为什么会发生这种情况吗? 我是否应该放弃使用xammvvm进行路由,转而使用其他方法 扬声器的ViewModel代码如下所示: using System; using System.Collections.Generic;

我们正在使用Xamarin.Forms和ReactiveUI构建一个跨平台的应用程序。 应用程序结构基于以下示例:

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);
            });
        }
    }
}

这是一个Xamarin。Forms bug。你可以看到这里的讨论

下面是bug本身:


在第一个链接中,您可以找到一些解决方法,其中一个非常简单的方法是更改可观察集合的反应列表。

您可以尝试更新到RxUI 7.2吗
<?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);
            });
        }
    }
}
{
  "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": {}
  }
}