question

78669366 avatar image
0 Votes"
78669366 asked KyleWang-MSFT edited

Handling ui while data loading

Hi

I have an UpcomingJobsPage page as below as well as the corresponding UpcomingJobsViewModel viewmodel. Its doing pretty standard stuff binding a listview to an observable collection and loading data into observable collection from a web api. Unfortunately the web api does not provide async method to load data.

The problem is that when user selects UpcomingJobsPage page from the burger menu the app gets stuck while data is being loaded from web api (line 'UpcomingJobsList = //... Call to web api' below).

What is a more graceful and elegant way to handle this for a better user experience?

Thanks

Regards


UpcomingJobsPage.xaml code:

       <RefreshView x:DataType="viewmodels:UpcomingJobsViewModel" 
                              Command="{Binding LoadItemsCommand}" >
        
                     <ListView x:Name="UpcomingJobsListView" 
                                            ItemsSource="{Binding UpcomingJobsList}" >
                     ...
        
                     </ListView>
        </RefreshView>


UpcomingJobsViewModel Code:

  class UpcomingJobsViewModel : MyViewModel  //MyViewModel is derived from baseViewModel with additional properties etc
         {
        
             public Command LoadItemsCommand { get; }
        
             ObservableCollection<UpcomingJobs> items;
             public ObservableCollection<UpcomingJobs> UpcomingJobsList
             {
                 get { return items; }
                 set { SetProperty(ref items, value); }
             }
        
             public UpcomingJobsViewModel()
             {
                 UpcomingJobsList = new ObservableCollection<UpcomingJobs>();
                 LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
             }
        
             private async Task ExecuteLoadItemsCommand()
             {
                 await LoadUpcomingJobsAsync();
             }
        
             private async Task LoadUpcomingJobsAsync(Expression<Func<UpcomingJobs, bool>> predicate = null)
             {
                 //Load data from web api here
                 UpcomingJobsList =   //... Call to web api
             }
        
         }
dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

KyleWang-MSFT avatar image
0 Votes"
KyleWang-MSFT answered KyleWang-MSFT edited

Hi 78669366,

Welcome to our Microsoft Q&A platform!

You can enable ListView's "IsPullToRefreshEnabled" property to achieve item refreshing. And bind "LoadItemsCommand" to "RefreshCommand" and set "IsRefreshing".

The following the demo xaml.

 <ListView x:Name="UpcomingJobsListView" 
             ItemsSource="{Binding UpcomingJobsList}" 
             IsPullToRefreshEnabled="True"
             RefreshCommand="{Binding LoadItemsCommand}"
             IsRefreshing="{Binding IsBusy, Mode=OneWay}"
             RefreshControlColor="Red">
     <ListView.ItemTemplate>
         <DataTemplate>
             <ViewCell>
                 <Label Text="{Binding Name}"/>
             </ViewCell>
         </DataTemplate>
     </ListView.ItemTemplate>
 </ListView>

Now you can use "Task.Run" to perform time-consuming operations and set "IsBusy" to false when the task is finished.

 private void LoadUpcomingJobsAsync()
 {
     IsBusy = true;
    
     Task.Run(() =>
     {
         //Load data from web api here
         // time consuming operations here
     }).ContinueWith((t) =>
     {
         IsBusy = false;
     });
 }

Regards,
Kyle


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.