Property Is Never Updated after Task Completes

时间:2017-08-04 12:12:40

标签: c# listview xamarin mvvm

I have a list view that has it's IsRefreshing property binding back to a viewmodel's IsBusy property; side note i am going for an MVVM approach. The issue is this, when IsBusy is set to false, it never removes the spinning circle on the list view and it's as if the property never changes. The IsBusy property is set something like this:

public RelayCommand LoadItemsCommand
{
    get
    {
        return _loadItemsCommand
                ?? (_loadItemsCommand = new RelayCommand(
                    () =>
                    {
                        SetItems();
                    }));
    }
}


public async void SetItems()
{
    try
    {
        IsBusy = true;
        List<Item> getItems = await service.GetItems();

            //SETTING LISTS

        selectedItem = null;
        searchString = string.Empty;

        IsBusy = false;
    }
    catch (Exception a)
    {
        //log it
        IsBusy = false;
    }
}

The Set() function is being called within a page load commnad. Originally, this try/catch block was in the page load command, but tried this route as the IsBusy property never seemed to stop the listview from showing the spinning circle. I do know that this viewmodel is hooked up correctly to the view as the commands and other properties do work as they should.

private bool _IsBusy;
public bool IsBusy
{
    get { return _IsBusy; }
    set { Set("IsBusy", ref _IsBusy, value); }
}

And that is the property.

<ListView ItemsSource="{Binding items}"
                  RefreshCommand="{Binding LoadItemsCommand}"
                  IsPullToRefreshEnabled="true"
                  SelectedItem="{Binding selectedItem}"
                  IsRefreshing="{Binding IsBusy}"
                  Style="{StaticResource listViewStyle}">
        <!-- OTHER LISTVIEW STUFF -->
</ListView>

And that's the view

1 个答案:

答案 0 :(得分:1)

您还应该尽量避免使用async void,除非它是一个事件处理程序。

您可以通过执行以下操作来创建异步RelayCommand ...

private Lazy<RelayCommand> _loadItemsCommand = new Lazy<RelayCommand>(() =>
    new RelayCommand(async () => await SetItems())
);
public RelayCommand LoadItemsCommand 
    get {
        return _loadItemsCommand.Value;
    }
}

public async Task SetItems() {
    try {
        IsBusy = true; // On UI Thread
        var getItems = await service.GetItems(); //asynchronous task on a background thread

        //Back on the UI Thread

        //SETTING LISTS

        selectedItem = null;
        searchString = string.Empty;

        IsBusy = false; // On UI Thread
    } catch (Exception a) {
        //log it
        IsBusy = false;
    }
}