Efficiently Handle Large Datasets with Seamless Pagination in .NET MAUI ListView


TL;DR: Struggling with performance issues in your .NET MAUI app due to large datasets? Learn how to efficiently handle them by implementing pagination with Syncfusion controls. Improve app performance, reduce memory usage, and ensure a smooth user experience when dealing with large ListView collections.
Managing large datasets in mobile applications can be a major challenge, especially when performance and responsiveness are top priorities. In .NET MAUI, loading large collections into a ListView without optimization often leads to sluggish UI and memory issues.
In this post, you’ll learn how to implement efficient pagination using Syncfusion’s ListView control in .NET MAUI. By breaking data into manageable pages, you can deliver a smooth and responsive experience, even when working with thousands of items.
Note: Before proceeding, refer to the Getting Started with .NET MAUI ListView documentation.
Implementing pagination in .NET MAUI ListView
Here’s a step-by-step guide to implementing pagination in the .NET MAUI ListView:
Step 1: Set up the data model
Create a data model to bind it to the control. In a new class file, set up a simple data source, as shown in the code example below.
PlaceInfo.cs
public class PlaceInfo : INotifyPropertyChanged
{
#region Fields
private string? name;
private string? description;
private string? image;
#endregion
#region Constructor
public PlaceInfo()
{
}
#endregion
#region Properties
public string? Name
{
get {return name;}
set
{
name = value;
OnPropertyChanged("Name");
}
}
public string? Description
{
get
{
return description;
}
set
{
description = value;
OnPropertyChanged("Description");
}
}
public string? Image
{
get
{
return image;
}
set
{
image = value;
OnPropertyChanged("Image");
}
}
#endregion
#region Interface Member
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
#endregion
}
Step 2: Implement the ViewModel
Create a model repository class with the Places collection property initialized with the required number of data objects in a new class file, as shown in the code example below.
PagingViewModel.cs
public class PagingViewModel : INotifyPropertyChanged
{
#region Fields
public ObservableCollection<PlaceInfo>? Places {get; set;}
#endregion
#region Constructor
public PagingViewModel()
{
places = new ObservableCollection<PlaceInfo>();
GenerateSource();
}
#endregion
#region Methods
private void GenerateSource()
{
---------------------
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
#endregion
}
Step 3: Define the UI
Install Required NuGet Packages
You need to install Syncfusion.Maui.DataGrid NuGet package, as SfDataPager is included in it.
Defining DataPager
XAML page includes the necessary namespaces to reference Syncfusion controls and defines the UI representation of a data pagination control in your .NET MAUI app using Syncfusion’s SfDataPager
Refer to the code example below.
xmlns:DataPager="clr-namespace:Syncfusion.Maui.DataGrid.DataPager;assembly=Syncfusion.Maui.DataGrid"
<DataPager:SfDataPager x:Name="dataPager"
Grid.Row="1"
Margin="7.5,11.5,7.5,11.5"
HorizontalOptions="Fill"
VerticalOptions="Center"
HeightRequest="36"
ButtonSize="36"
ButtonSpacing="8"
ButtonFontSize="14"
NumericButtonCount="8">
</DataPager:SfDataPager>
Defining the item template
Now, we will create the UI for showing the places collection by using the .NET MAUI ListView. Install the necessary package to use the control in the application.
To define the ItemTemplate for a ListView that displays place information, and create a custom template that includes controls like labels and images for displaying place details.
Refer to the code example below.
<ListView:SfListView x:Name="verticalListView"
Grid.Row="0"
AutoFitMode="DynamicHeight"
SelectionMode="Single">
<ListView:SfListView.ItemTemplate>
<DataTemplate x:DataType="local:PlaceInfo">
-----------------------------
<Image Grid.Column="0" Source="{Binding Image}" Aspect="Fill" HeightRequest="44" WidthRequest="44"/>
</Border>
<Grid Grid.Column="1" VerticalOptions="Center" RowSpacing="4">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0"
Text="{Binding Name}"
FontSize="14"
FontFamily="Roboto-Regular"
CharacterSpacing="0.25"
TextColor="Black"/>
<Label Grid.Row="1" Text="{Binding Description}"
TextColor="DimGray"
FontSize="14" FontFamily="Roboto-Regular" LineBreakMode="TailTruncation" CharacterSpacing="0.15"/>
---------------------------------
</DataTemplate>
</ListView:SfListView.ItemTemplate>
</ListView:SfListView>
Step 4: Handling page change in Behavior
The behavior class provides a structured way of implementing paging in your MAUI application using Syncfusion’s controls. This mechanism ensures that only the required data is loaded at any time, greatly improving performance for large datasets. It utilizes Syncfusion’s SfDataPager to control the flow of data and dynamically load items as the user navigates through different pages. This approach helps in efficiently managing memory and providing a smooth user experience, especially when dealing with large datasets.
Refer to the code example below.
public class SfListViewPagingBehavior : Behavior<ContentPage>
{
#region Fields
private Syncfusion.Maui.ListView.SfListView? listView;
private PagingViewModel? pagingViewModel;
private SfDataPager? dataPager;
#endregion
protected override void OnAttachedTo(ContentPage bindable)
{
listView = bindable.FindByName<Syncfusion.Maui.ListView.SfListView>("verticalListView");
dataPager = bindable.FindByName<SfDataPager>("dataPager");
pagingViewModel = new PagingViewModel();
listView.BindingContext = pagingViewModel;
dataPager.OnDemandLoading += DataPager_OnDemandLoading;
base.OnAttachedTo(bindable);
}
private void DataPager_OnDemandLoading(object? sender, OnDemandLoadingEventArgs e)
{
var source = pagingViewModel!.places!.Skip(e.StartIndex).Take(e.PageSize);
listView!.ItemsSource = source.AsEnumerable();
}
protected override void OnDetachingFrom(ContentPage bindable)
{
dataPager!.OnDemandLoading -= DataPager_OnDemandLoading;
listView = null;
pagingViewModel = null;
dataPager = null;
base.OnDetachingFrom(bindable);
}
}
When a new page is requested, this method is called with the StartIndex and PageSize in the OnDemandLoading event. It uses these parameters to skip certain records and take the required number to form the page.
You will get the following output when executing the previous code cumulatively.
On-Demand loading events
Conclusion
Thanks for reading! In this blog, we’ve implemented pagination with Syncfusion’s .NET MAUI ListView, a powerful way to boost performance when working with large datasets. By reducing the data load per view and improving rendering efficiency, you can enhance the overall user experience in your mobile apps.
Explore Syncfusion’s full suite of MAUI controls to take advantage of more performance-optimized features that simplify your app development process.
Are you already a Syncfusion® user? If so, you can download the product setup here. If not, you can download a 30-day free trial.
If you have questions, contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!
Related Blogs
Subscribe to my newsletter
Read articles from syncfusion directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

syncfusion
syncfusion
Syncfusion provides third-party UI components for React, Vue, Angular, JavaScript, Blazor, .NET MAUI, ASP.NET MVC, Core, WinForms, WPF, UWP and Xamarin.