Run the background data-fetch as a separate task using Task.Run() and use Xamarin.Essentials.MainThread.BeginInvokeOnMainThread wherever you need to shift on the main UI thread.
How can I execute a method after a content page is visible in Xamarin Forms?
In my Xamarin Forms app made for android as of now, I have a stack layout that gets populated based on a list that needs to fetch data from local sqlite DB. The data is around 200 rows. The stack needs to be populated when the ContentPage appears in foreground. Since this process takes a bit of time, the navigation to this page is taking some time which leads to poor performance of app. I have added that refresh method in constructor of page and also have tried putting it in OnAppearing override method. But the transition occurs only when the stack is populated. Is there any way to view the page to the user first (make navigation happen) and then populate the stack?
Developer technologies | .NET | Xamarin
-
Rahul Choudhary 96 Reputation points
2021-07-14T05:35:45.09+00:00
1 additional answer
Sort by: Most helpful
-
Kyle Wang 5,531 Reputation points Microsoft External Staff
2021-07-14T05:30:51.513+00:00 Hi RahulChoudhary-0493,
Welcome to our Microsoft Q&A platform!
Xamarin.Forms only provides two lifecycle-type events: OnAppearing and OnDisappearing. So there is no event to monitor "page loaded".
If you want to load a large amount of data, the general approach is to use async/await.
MainPage.xaml:
<Button Text="ObservableCollection" Command="{Binding ToListCommand}"/>MainPage.xaml.cs:
BindingContext = new MainPageViewModel(Navigation);DetailPage.xaml:
<ListView ItemsSource="{Binding Source}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Label Text="{Binding Name}"/> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>DetailPage.xaml.cs:
BindingContext = MainPageViewModel.model;MainPageViewModel.cs:
class Student { public string Name { get; set; } public string Address { get; set; } } class MainPageViewModel : INotifyPropertyChanged { public static MainPageViewModel model; DetailPage detail; INavigation Navigation { get; } public List<Student> Temp { get; set; } List<Student> source; public List<Student> Source { get => source; set { source = value; OnPropertyChanged("Source"); } } public ICommand ToListCommand { get; } public MainPageViewModel(INavigation navigation) { model = this; detail = new DetailPage(); Navigation = navigation; ToListCommand = new Command(async () => { await Load(); }); Source = new List<Student>(); Temp = new List<Student>(); } async Task Load() { await Navigation.PushAsync(detail); await Task.Run(() => { for (int i = 0; i < 300; i++) { Temp.Add(new Student { Name = $"Name{i}", Address = $"Address{i}" }); } Source = Temp; }); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } }Besides, you can try the incremental data loading provided in CollectionView. For more info, you can refer to this answer.
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.