Search code examples
mauiactivity-indicator

Global activity indicator issue in MAUI using AppShell header and its properties


I am trying to create Activity indicator using AppShell Flyoutheader and IsBusy property. Once IsBusy is set to true, while trying setting it false, crashing the application. I have also tried setting it on a different thread but no luck.

Here is how I am trying to do it:

AppShell:

 <Shell.FlyoutHeader>
     <StackLayout x:Name="profileCard">
         <ActivityIndicator IsRunning="{Binding IsBusy}"
                                IsVisible="{Binding IsBusy}"
                                HorizontalOptions="Center"
                                VerticalOptions="Center"
                                Color="Red" />
                                ......
     </StackLayout>
 </Shell.FlyoutHeader>

All pages/component of the app are calling a generic extension method to get the data. I am setting IsBusy to True and False there:

 public async static Task<List<T>> GetAsync<T>(Expression<Func<T, bool>>? predicate = null, bool includeActiveOnly = true) where T : BaseModel, new()
 {
     Shell.Current.IsBusy = true;
    
     var query = DbContext.Table<T>();

     if (includeActiveOnly)
         query = query.Where(x => x.IsActive == true);

     if (predicate != null)
         query = query.Where(predicate);

     query = query.OrderByDescending(x => x.DateAdded);
    
     var list = await query.ToListAsync();
     Shell.Current.IsBusy = false
    
     return list;
 }

I tried this as well but app is crashing again. await Task.Run(() => Shell.Current.IsBusy = false);

Any help is much appreciated.


Solution

  • Well, sorted out the issue as follows:

    I took the generic repository and my extension methods to the library project(Which was planned originally).

    Setting Shell's IsBusy property using MainThread as follows

    public async static Task<List<T>> GetAsync<T>(Expression<Func<T, bool>>? predicate = null, bool includeInactive = false, bool includeArchived = true, int? take = null) where T : BaseModel, new()
    {
    
     MainThread.BeginInvokeOnMainThread(() => { if (!Shell.Current.IsBusy) Shell.Current.IsBusy = true; });
    
     var query = DbContext.Table<T>();
    
     if (includeInactive)
         query = query.Where(x => x.IsActive == true || x.IsActive == false);
     else
         query = query.Where(x => x.IsActive == true);
    
     if (predicate != null)
         query = query.Where(predicate);
    
     if (take != null)
         query = query.Take(take.GetValueOrDefault());
    
     query = query.OrderByDescending(x => x.DateAdded);
    
     var list = await query.ToListAsync();
    
     MainThread.BeginInvokeOnMainThread(() => { if (Shell.Current.IsBusy) Shell.Current.IsBusy = false; });
     return list;
    

    }

    Activity Indicator is binding to Shell's IsBusy property.