MvvmCross.Forms - Default Spinner will not exit

67 Views Asked by At

This bug exists in the Sample files (StarWarsSample) and I have been trying to remove it for SEVERAL hours... any advice is appreciated:

Using MvvmCross.Forms

I have an MvxListView which has RefreshCommand bound to a command. I have confirmed it fires. When the MvxListView is pulled down (both iOS and Android) a spinner appears. However it never disappears. I do not have any exceptions being thrown. If I raise a dialog it appears over the spinner, but then once cancelled the spinner remains. My ListView is dynamically updating fine. Just the spinner never disappears... I'm assuming it's coming from some specific function in MVVMCross/Forms but i cannot seem to find any reference to it.

Here's the relevant code (in it's current state after trying different approaches)

 <views:MvxListView 
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand"
            SelectionMode="None"
            ItemsSource="{mvx:MvxBind BtDevices}" 
            ItemClick="{mvx:MvxBind BtDeviceSelectedCommand}"
            IsPullToRefreshEnabled="True" 
            RefreshCommand="{mvx:MvxBind RefreshBtDevicesCommand}"
            ItemTemplate="{StaticResource DeviceNameTemplate}"
            RowHeight="{x:OnPlatform Android=55, iOS=55, UWP=40}"
            BackgroundColor="LightBlue"
            SeparatorVisibility="None">
           
        </views:MvxListView>

 public HomeViewModel(...){
BtDevices = new MvxObservableCollection<BtDevice>();

        BtDeviceSelectedCommand = new MvxAsyncCommand<IBtDevice>(BtDeviceSelected);
        FetchBtDevicesCommand = new MvxCommand(() =>
        { 
            FetchBtDeviceTask = MvxNotifyTask.Create(LoadDevices, onException: OnException);
            RaisePropertyChanged(() => FetchBtDeviceTask);
        });

        RefreshBtDevicesCommand = new MvxCommand(()=>
        {
            RefreshDeviceTask = MvxNotifyTask.Create(RefreshBtDevices, OnException);
            RaisePropertyChanged(() => RefreshDeviceTask);
        });
}
 private async Task RefreshBtDevices()
    {
        IsBusy = true;
        var result = await _btService.LoadDevices(_nextPage);

        foreach (var d in result.Where(d => BtDevices.FirstOrDefault(i => i.Id == d.Id) == null))
        {
            BtDevices.Add(d);
        }

        IsBusy = false;

        await RaisePropertyChanged(() => RefreshDeviceTask);
        await RaisePropertyChanged(() => RefreshBtDevicesCommand);
        
    }
1

There are 1 best solutions below

1
fmaccaroni On

From the docs you need to bind the IsRefreshing property of the list view.

Gets or sets a value that tells whether the list view is currently refreshing

Something like this:

IsRefreshing="{mvx:MvxBind IsBusy}"

or if you are using an MvxNotifyTask:

IsRefreshing="{mvx:MvxBind RefreshDeviceTask.IsNotCompleted}"

Here you have more informaion, even though it uses directly ListView on the example the same can be applied to MvxListView given that it inherits from ListView.

HIH