[FIXED] State of RefreshView is invoking RefreshCommand in .NET MAUI

Issue

I have a CollectionView in my .NET MAUI app and I placed it inside a RefreshView. When I call my API to populate this CollectionView, I cache the data so that I don’t have to keep making API calls everytime the user hits this page.

In order to streamline my code, I created a private method in my view model that calls my API. The view model looks like this:

public partial MyViewModel : BaseViewModel
{
   ObservableCollection<MyModel> MyData { get; } = new();

   [RelayCommand]
   async Task RefreshData()
   {
      IsBusy = true;

      await GetData(true);

      IsBusy = false;
   }

   private async Task GetData(bool shouldGetFreshData)
   {
       // Makes API call to get data, then assigns it to MyData collection
   }

   public async void Init()
   {
       IsBusy = true;

       await GetData(false);
 
       IsBusy = false;
   }
}

The XAML for the page looks like this:

<RefreshView
   IsRefreshing={Binding IsBusy}
   Command={Binding RefreshDataCommand}>
   <CollectionView>
   ...
   </CollectionView>
</RefreshView>

I also wired the page to use the MyViewModel as its view model AND OnAppearing(), I call the Init() method of the view model.

Here’s what I was expecting which is NOT what’s happening:

I thought, the Init() would get called first which then calls the GetData() method with false input parameter. This way, I could use the cached data. And whenever, the user refreshes the CollectionView by pulling it down, the RefreshData() method would be called with true as the input parameter which would force the code to make an API call.

Instead of what I was expecting, here’s what’s happening:

  1. The Init() method gets called first and as a result, the line with IsBusy = true executes.
  2. This then ends up invoking the RefreshData() method
  3. Then the await GetData(false) in Init() method executes
  4. Then the await GetData(true) in RefreshData() method executes

As a result of all this, the GetData() method gets called twice.

I think, what’s triggering this is the IsBusy. I thought IsBusy would only serve as an indicator but not necessarily invoke the RefreshData() method which is bound to the Command of my RefreshView.

Is this normal behavior or am I missing something here?

Solution

Apparently, this is "normal" behavior because I’m manually setting IsBusy to true. I decided to leave this question here because this may be a pitfall that affects others.

Here’s the actual section in documentation that states this:
enter image description here

And here’s the documentation: https://docs.microsoft.com/en-us/dotnet/maui/user-interface/controls/refreshview

So, all I had to do is remove the IsBusy = true in Init() method.

Answered By – Sam

Answer Checked By – Dawn Plyler (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published