.NET MAUI Grouping, Filtering, Sorting Items Step by step Implementation and Top 10 Questions and Answers
 Last Update: April 01, 2025      17 mins read      Difficulty-Level: beginner

.NET MAUI Grouping, Filtering, Sorting Items: A Comprehensive Guide

When developing rich, data-driven applications with .NET Multi-platform App UI (MAUI), you often encounter scenarios where the raw data needs to be organized and displayed efficiently. Grouping, filtering, and sorting items are essential operations that help manage and display large datasets comprehensively. In this article, we will delve into each of these concepts and demonstrate how to implement them in .NET MAUI.

Grouping Items

Grouping is a method of organizing your data into categories or sections based on a particular property. This feature is especially useful when dealing with lists that contain multiple entries with common attributes.

Implementing Grouping

To group items in .NET MAUI, you can use the ObservableGroupCollection<TKey, TItem> class, which automatically organizes and handles groups in a collection.

  1. Define Your Data Models

    First, ensure you have the appropriate data models. For example, if you are working with a collection of books, you might have the following models:

    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public string Genre { get; set; }
    }
    
  2. Create the Grouped Collection

    Use the ObservableGroupCollection<TKey, TItem> to create a grouped collection where the TKey is the property by which items are grouped, and TItem is the data model.

    var books = new List<Book>
    {
        new Book { Title = "1984", Author = "George Orwell", Genre = "Dystopian" },
        new Book { Title = "Brave New World", Author = "Aldous Huxley", Genre = "Dystopian" },
        new Book { Title = "Pride and Prejudice", Author = "Jane Austen", Genre = "Romance" }
    };
    
    var groupedBooks = new ObservableGroupCollection<string, Book>(books, book => book.Genre);
    
  3. Display in XAML

    Bind the grouped collection to a ListView or CollectionView in XAML and use data templates to define the group headers and item layouts.

    <CollectionView ItemsSource="{Binding GroupedBooks}">
        <CollectionView.GroupTemplate>
            <DataTemplate>
                <GroupHeaderTemplate>
                    <Label Text="{Binding Key}" FontSize="18" FontAttributes="Bold" />
                </GroupHeaderTemplate>
            </DataTemplate>
        </CollectionView.GroupTemplate>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Title}" />
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    

Filtering Items

Filtering enables you to show only a subset of data based on specific criteria. This functionality is critical for applications needing to search through data quickly and efficiently.

Implementing Filtering

You can implement filtering using a combination of ObservableCollection<T> or ObservableGroupCollection<TKey, TItem> along with a filtering mechanism.

  1. Define Your Filter Logic

    Create a method that takes the collection and a filter condition as input and returns a filtered collection.

    public ObservableCollection<Book> FilterBooks(IEnumerable<Book> books, string searchTerm)
    {
        return new ObservableCollection<Book>(
            books.Where(book => book.Title.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)));
    }
    
  2. Bind to the UI

    In your XAML, bind an Entry to capture the search term and a CollectionView to display the filtered results.

    <Entry Text="{Binding SearchTerm, Mode=TwoWay}" PlaceholderText="Search..." />
    <CollectionView ItemsSource="{Binding FilteredBooks}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Title}" />
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    
  3. Execute the Filter

    In your ViewModel, update the FilteredBooks collection whenever the SearchTerm changes.

    public ObservableCollection<Book> FilteredBooks { get; set; }
    private string _searchTerm;
    
    public string SearchTerm
    {
        get => _searchTerm;
        set
        {
            _searchTerm = value;
            FilteredBooks = FilterBooks(books, value);
            OnPropertyChanged(nameof(FilteredBooks));
        }
    }
    

Sorting Items

Sorting allows you to order items based on a specific property, providing a structured and logical presentation of the data.

Implementing Sorting

You can sort data using LINQ or by implementing custom sorting logic.

  1. Define Your Sorting Criteria

    Create a method that takes the collection and a sorting key as input and returns a sorted collection.

    public ObservableCollection<Book> SortBooks(IEnumerable<Book> books, string sortKey)
    {
        switch (sortKey)
        {
            case "Title":
                return new ObservableCollection<Book>(books.OrderBy(book => book.Title));
            case "Author":
                return new ObservableCollection<Book>(books.OrderBy(book => book.Author));
            case "Genre":
                return new ObservableCollection<Book>(books.OrderBy(book => book.Genre));
            default:
                return new ObservableCollection<Book>(books);
        }
    }
    
  2. Bind to the UI

    Add a Picker or Button to allow the user to select the sorting method and a CollectionView to display the sorted data.

    <Picker ItemsSource="{Binding SortKeys}" SelectedItem="{Binding SelectedSortKey, Mode=TwoWay}" />
    <CollectionView ItemsSource="{Binding SortedBooks}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Title}" />
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    
  3. Execute the Sort

    In your ViewModel, update the SortedBooks collection whenever the SelectedSortKey changes.

    public ObservableCollection<Book> SortedBooks { get; set; }
    private string _selectedSortKey;
    
    public string SelectedSortKey
    {
        get => _selectedSortKey;
        set
        {
            _selectedSortKey = value;
            SortedBooks = SortBooks(books, value);
            OnPropertyChanged(nameof(SortedBooks));
        }
    }
    

Conclusion

In .NET MAUI, effectively organizing data through grouping, filtering, and sorting not only enhances the user experience but also makes your application's data management more robust. By leveraging the capabilities of ObservableGroupCollection<TKey, TItem>, LINQ, and data binding, you can create powerful and flexible data-driven applications. Implementing these features requires a solid understanding of data models, collection types, and UI bindings, but the end result is a polished and intuitive interface that users will appreciate.

Examples, Set Route and Run the Application: Step-by-Step for Beginners on .NET MAUI Grouping, Filtering, and Sorting Items

Introduction

Welcome to the world of .NET Multi-platform App UI (MAUI), Microsoft's modern framework for building cross-platform mobile and desktop applications. In this guide, we will explore the critical aspects of handling data in a .NET MAUI application, specifically focusing on grouping, filtering, and sorting items. This will be a step-by-step tutorial aimed at beginners, so if you're new to .NET MAUI, you're in the right place.

Setting Up Your Project

Before we dive into the specifics of grouping, filtering, and sorting, we need to set up our project correctly.

  1. Install .NET MAUI SDK:

    • Ensure that you have the latest .NET SDK installed. You can download it from the .NET website.
    • Make sure that the .NET MAUI workload is installed. You can check this in Visual Studio under Tools > Get Tools and Features > Individual Components and look for .NET Multi-platform App UI development.
  2. Create a New .NET MAUI Project:

    • Open Visual Studio and create a new project.
    • Choose "MAUI App" from the available templates.
    • Give your project a name and select a location to save it, then click "Create."
  3. Set Up the Navigation:

    • For simplicity, we will use a single page for our example. However, if your application involves multiple pages, you can set up navigation using Shell or NavigationPage.

Example Data Model

Let's create a simple data model for our example.

  1. Create the Item Model:
    • Create a new class named Item.cs.
public class Item
{
    public string Name { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; }
}
  1. Add Sample Data:
    • Create a new service or class to provide sample data. This could be a static list or fetched from a database.
public class ItemService
{
    public static List<Item> GetItems()
    {
        return new List<Item>
        {
            new Item { Name = "Apple", Category = "Fruits", Price = 1.20m },
            new Item { Name = "Banana", Category = "Fruits", Price = 0.90m },
            new Item { Name = "Carrot", Category = "Vegetables", Price = 0.70m },
            new Item { Name = "Broccoli", Category = "Vegetables", Price = 1.00m },
            new Item { Name = "Chicken", Category = "Meat", Price = 5.50m },
            new Item { Name = "Beef", Category = "Meat", Price = 7.00m }
        };
    }
}

Setting Up the User Interface (XAML)

Let's create a simple UI to display our items.

  1. MainPage.xaml:
    • Open MainPage.xaml and set up a CollectionView to display the items.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourNamespace"
             x:Class="YourNamespace.MainPage">

    <CollectionView x:Name="ItemsCollectionView">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10" ColumnDefinitions="*, Auto, Auto">
                    <Label Grid.Column="0" Text="{Binding Name}" FontAttributes="Bold" />
                    <Label Grid.Column="1" Text="{Binding Category}" Margin="10, 0, 0, 0" />
                    <Label Grid.Column="2" Text="{Binding Price, StringFormat='${0:C}'}" Margin="10, 0, 0, 0" HorizontalTextAlignment="End" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

Adding Data Binding (Code-Behind)

Let's bind our UI to the data.

  1. MainPage.xaml.cs:
    • Open MainPage.xaml.cs and set the data source for the CollectionView.
public partial class MainPage : ContentPage
{
    public ObservableCollection<Item> Items { get; set; }

    public MainPage()
    {
        InitializeComponent();

        Items = new ObservableCollection<Item>(ItemService.GetItems());
        ItemsCollectionView.ItemsSource = Items;
    }
}

Grouping Items

To group items, we need to use the Group method in LINQ.

  1. Group by Category:
    • Modify the MainPage.xaml.cs to group items by their category.
public partial class MainPage : ContentPage
{
    public ObservableCollection<Grouping<string, Item>> GroupedItems { get; set; }

    public MainPage()
    {
        InitializeComponent();

        var items = ItemService.GetItems();
        var groupedItems = from item in items
                           orderby item.Category
                           group item by item.Category into g
                           select new Grouping<string, Item>(g.Key, g);

        GroupedItems = new ObservableCollection<Grouping<string, Item>>(groupedItems);
        ItemsCollectionView.ItemsSource = GroupedItems;
        ItemsCollectionView.IsGroupingEnabled = true;
        ItemsCollectionView.GroupDisplayBinding = new Binding("Key");
    }
}
  1. Grouping Class:
    • Create a new class Grouping to support grouping.
public class Grouping<TKey, TValue> : List<TValue>
{
    public TKey Key { get; private set; }

    public Grouping(TKey key, IEnumerable<TValue> items)
    {
        Key = key;
        foreach (var item in items)
        {
            this.Add(item);
        }
    }
}

Filtering Items

To filter items, we will add a search functionality.

  1. Search Entry:
    • Add a SearchBar to the UI in MainPage.xaml.
<SearchBar x:Name="SearchBar" Placeholder="Search items..." TextChanged="SearchBar_TextChanged" />
  1. Search Logic:
    • Add a TextChanged event handler in MainPage.xaml.cs.
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
    if (string.IsNullOrWhiteSpace(e.NewTextValue))
    {
        ItemsCollectionView.ItemsSource = GroupedItems;
    }
    else
    {
        var filteredItems = ItemService.GetItems().Where(i => i.Name.Contains(e.NewTextValue, StringComparison.OrdinalIgnoreCase));

        var grouped = from item in filteredItems
                      orderby item.Category
                      group item by item.Category into g
                      select new Grouping<string, Item>(g.Key, g);

        ItemsCollectionView.ItemsSource = new ObservableCollection<Grouping<string, Item>>(grouped);
    }
}

Sorting Items

To sort items, we will allow sorting by different criteria.

  1. Sorting Button:
    • Add a button to sort items in MainPage.xaml.
<Button Text="Sort by Price" Clicked="SortButton_Clicked" Margin="10" />
  1. Sorting Logic:
    • Add a Clicked event handler in MainPage.xaml.cs.
private void SortButton_Clicked(object sender, EventArgs e)
{
    var sortedItems = ItemService.GetItems().OrderBy(i => i.Price);

    var grouped = from item in sortedItems
                  orderby item.Category
                  group item by item.Category into g
                  select new Grouping<string, Item>(g.Key, g);

    ItemsCollectionView.ItemsSource = new ObservableCollection<Grouping<string, Item>>(grouped);
}

Running the Application

Now that we’ve covered all the steps, let’s run the application to see everything in action.

  1. Set the Startup Project:

    • In Solution Explorer, right-click on your .NET MAUI project and select "Set as StartUp Project."
  2. Select Target Platform:

    • Choose the target platform you want to test on (e.g., Android, iOS, Windows, macOS).
  3. Run the Application:

    • Click the "Start" button (F5) or press "Ctrl + F5" to run the application without debugging.

Conclusion

You now have a .NET MAUI application displaying grouped, filtered, and sortable items. This hands-on guide walked you through setting up the project, creating the data model, designing the UI, and implementing essential functionalities to manage your app's data effectively. Feel free to experiment with different data sources, UI enhancements, and features to make your application even more robust and user-friendly. Happy coding!

Top 10 Questions and Answers for .NET MAUI Grouping, Filtering, Sorting Items

1. What is .NET MAUI?

Answer: .NET MAUI (Multi-platform App UI) is a single codebase framework designed for building native user interface applications that run across multiple platforms, including Windows, macOS, iOS, and Android. It leverages the power of .NET and the Model-View-ViewModel (MVVM) architecture pattern, making it easier for developers to create rich, performant apps for a variety of devices.

2. How can I group items in a collection using .NET MAUI?

Answer: Grouping items in .NET MAUI is typically done using the ObservableGroupedCollection or GroupedCollection within your data model. Suppose you have a collection of employees, and you want to group them by the department. Here's how:

ObservableCollection<Employee> employees = GetEmployees();
var groupedEmployees = new ObservableGroupedCollection<string, Employee>(
    employees.GroupBy(emp => emp.Department).Select(g => new Grouping<string, Employee>(g.Key, g))
);

Then, you can bind groupedEmployees to a CollectionView or ListView in your XAML:

<ListView ItemsSource="{Binding GroupedEmployees}">
    <ListView.GroupDisplayBinding>
        <Binding Path="Key" />
    </ListView.GroupDisplayBinding>
</ListView>

3. How to filter items in a collection with .NET MAUI?

Answer: To filter items in .NET MAUI, you generally use LINQ queries to modify the observable collection you are binding to. Assume you want to filter a list of products based on their price.

ObservableCollection<Product> products = GetProducts();
ObservableCollection<Product> filteredProducts = new ObservableCollection<Product>();

public void ApplyPriceFilter(float minPrice, float maxPrice)
{
    filteredProducts.Clear();
    filteredProducts.AddRange(products.Where(prod => prod.Price >= minPrice && prod.Price <= maxPrice));
}

Bind filteredProducts to a CollectionView in XAML and re-invoke ApplyPriceFilter as required.

4. How can I sort items in .NET MAUI?

Answer: Sorting items in a collection in .NET MAUI is straightforward and can be achieved using LINQ's ordering methods (OrderBy, OrderByDescending). Example: Sort a list of products by name in ascending order.

ObservableCollection<Product> products = GetProducts();
products = new ObservableCollection<Product>(products.OrderBy(p => p.Name));

Or sort by price in descending order:

products = new ObservableCollection<Product>(products.OrderByDescending(p => p.Price));

5. How can I combine grouping, filtering, and sorting in .NET MAUI?

Answer: You can combine these operations by chaining LINQ queries. Assume you want to filter products under a specific price, group them by category, and sort within each group alphabetically:

var filteredAndGroupedProducts = GetProducts()
    .Where(p => p.Price < 100)
    .GroupBy(p => p.Category)
    .Select(g => new Grouping<string, Product>(g.Key, g.OrderBy(p => p.Name)));

Bind filteredAndGroupedProducts to your UI accordingly.

6. Is it possible to perform real-time filtering in .NET MAUI?

Answer: Yes, real-time filtering can be achieved by handling input events (e.g., TextChanged in Entry) and updating the filtered collection based on the user's input.

private void OnSearchTextChanged(object sender, TextChangedEventArgs e)
{
    string searchTerm = e.NewTextValue.ToLower();

    ApplySearchFilter(searchTerm);
}

private void ApplySearchFilter(string filter)
{
    if (string.IsNullOrWhiteSpace(filter))
    {
        // Display all products
        filteredProducts.Clear();
        filteredProducts.AddRange(GetProducts());
    }
    else
    {
        // Filter and display matching products
        filteredProducts.Clear();
        filteredProducts.AddRange(GetProducts().Where(p => p.Name.ToLower().Contains(filter)));
    }
}

7. How to handle complex grouping in .NET MAUI?

Answer: Complex grouping can be handled by using nested groupings, which can be done by applying multiple GroupBy calls or creating a hierarchy in your data model. Here's an example of grouping employees by department and then by team:

var groupedEmployees = new ObservableGroupedCollection<string, ObservableGroupedCollection<string, Employee>>(
    employees
        .GroupBy(emp => emp.Department)
        .Select(d => new Grouping<string, ObservableGroupedCollection<string, Employee>>(
            d.Key,
            new ObservableGroupedCollection<string, Employee>(
                d.GroupBy(emp => emp.Team)
                     .Select(t => new Grouping<string, Employee>(t.Key, t))
            )
        ))
);

8. What are best practices for performance when grouping, filtering, and sorting large collections in .NET MAUI?

Answer:

  • Threading: Offload heavy processing to background threads using async and await.
  • Memory Efficient: Use ObservableCollection only where necessary. Consider using List for internal operations and convert to ObservableCollection when binding to UI elements.
  • Incremental Loading: Implement incremental loading to load data in chunks, reducing the amount of data processed at once.
  • Virtualization: Use virtualizing controls like CollectionView which only instantiate and render items visible in the viewport, improving performance.

9. How to bind collection operations to UI controls in .NET MAUI?

Answer: You can bind collection operations to UI controls using data binding. For example, to dynamically update a CollectionView when the underlying collection changes, do the following:

<CollectionView ItemsSource="{Binding GroupedProducts}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <!-- Your DataTemplate definition goes here -->
        </DataTemplate>
    </CollectionView.ItemTemplate>
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Text="{Binding Key}" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
</CollectionView>

Ensure your backing collection is an ObservableCollection or implements INotifyCollectionChanged to automatically update the UI when the data changes.

10. How to handle changes in grouping or filtering criteria dynamically in .NET MAUI?

Answer: To handle dynamic changes in grouping or filtering criteria, you can modify the underlying collection and raise property changed notifications if required. For example:

public class ViewModel : INotifyPropertyChanged
{
    private string _currentFilter;
    public string CurrentFilter
    {
        get => _currentFilter;
        set
        {
            _currentFilter = value;
            OnPropertyChanged(nameof(CurrentFilter));
            ApplyFilter();
        }
    }

    private void ApplyFilter()
    {
        filteredProducts.Clear();
        filteredProducts.AddRange(GetProducts().Where(p => p.Name.Contains(CurrentFilter)));
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Bind CurrentFilter to a UI element like an Entry, and filteredProducts to a CollectionView. The UI will automatically update as CurrentFilter changes.

By understanding and applying these concepts, developers can effectively manage and display collections in .NET MAUI with grouping, filtering, and sorting capabilities.