The previous four lessons took BiblioTech to the desktop (Windows Forms, WPF) and to the web (ASP.NET Core, Blazor). One platform remains: mobile devices. This last lesson of Module 7 introduces Xamarin.Forms, the framework that for years let you write cross-platform mobile applications in C#, and its official successor, .NET MAUI (Multi-platform App UI), to which Microsoft has migrated the entire ecosystem. You'll see why that change happened, what a project gains by adopting MAUI, and you'll build a simple mobile screen showing BiblioTech's catalog, with XAML that will feel very familiar after the WPF lesson. This closes out Module 7's tour of the main ways to give a C# application an interface.

Contents

  1. Xamarin.Forms: its historical role in mobile development with C#
  2. Why Microsoft replaced Xamarin.Forms with .NET MAUI
  3. What a project gains with .NET MAUI: a single cross-platform project
  4. Basic structure of a MAUI project
  5. ContentPage and XAML: similarities with WPF
  6. Complete example: a BiblioTech catalog screen with CollectionView
  7. Closing out Module 7 and the link to Module 8

  1. Xamarin.Forms: its historical role in mobile development with C#

Before Xamarin, developing an Android application required Java or Kotlin, and iOS required Objective-C or Swift: two completely separate codebases, needing two teams or twice the effort for the same application. Xamarin, acquired by Microsoft in 2016, made it possible to write that logic in C# and compile it natively for both platforms; Xamarin.Forms, specifically, further added a shared interface layer in XAML, so that not even the visual interface had to be written twice.

For several years, Xamarin.Forms was Microsoft's main route to cross-platform mobile development in C#, and a great many applications in production still run on it. It's important to recognize this if you come across existing Xamarin.Forms code: the XAML syntax and ContentPage concepts you'll see in this lesson are, to a large extent, the very same ones Xamarin.Forms introduced back then.

  1. Why Microsoft replaced Xamarin.Forms with .NET MAUI

Microsoft announced the end of support for Xamarin.Forms and its evolution into .NET MAUI as its official successor, integrated directly into .NET (starting with .NET 6), instead of being kept as a separate framework with its own lifecycle. The main reasons behind this change:

Xamarin.Forms limitation How .NET MAUI solves it
A project separate from the rest of the .NET ecosystem, with its own tools and release cycle Integrated into .NET from the ground up: same SDK, same dotnet new, same versions as the rest of the course
One project per platform (Android, iOS) with duplicated configuration A single cross-platform project (section 3)
No native support for desktop applications (Windows, macOS) Desktop support included from the initial design
An older rendering architecture, with more intermediate layers A more direct, better-performing handlers architecture

.NET MAUI, then, isn't a brand-new framework unrelated to Xamarin.Forms: it's its official evolution/successor, designed precisely to solve those architectural limitations and unify mobile development within the same .NET already used throughout the rest of this course. An existing Xamarin.Forms project can be migrated to .NET MAUI (Microsoft documents that path), but for a new project in 2026, the natural choice is MAUI from the start.

  1. What a project gains with .NET MAUI: a single cross-platform project

The most visible gain of MAUI over the original Xamarin.Forms is unification: a single .csproj project compiles for several target platforms, with no separate projects to maintain:

flowchart TD
    P["A single .NET MAUI project<br/>(BiblioTech.Mobile)"] --> A["Android"]
    P --> I["iOS"]
    P --> W["Windows"]
    P --> M["macOS (Mac Catalyst)"]

That same project can also share its XAML interface with a desktop WPF project — the basic control and binding syntax is very similar between WPF and MAUI, as you'll see in section 5 — and, of course, it can directly reference BiblioTech's existing domain classes (Library, Book, Member...), with no adaptation needed.

  1. Basic structure of a MAUI project

dotnet new maui -n BiblioTech.Mobile
BiblioTech.Mobile/
├── MauiProgram.cs
├── App.xaml
├── App.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
└── Platforms/
    ├── Android/
    ├── iOS/
    ├── Windows/
    └── MacCatalyst/
  • MauiProgram.cs: the application's startup point, where the services container is configured — the same dependency injection mechanism seen in ASP.NET Core and Blazor.
  • App.xaml/App.xaml.cs: the application itself, which decides which page to show on startup.
  • MainPage.xaml/.xaml.cs: the first screen, with the same XAML + code-behind pattern already known from WPF.
  • Platforms/: platform-specific code (native icons, permissions...), rarely needed for a simple application like this lesson's.
// MauiProgram.cs (fragment)
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        builder.Services.AddSingleton<Library>(); // same services container as ASP.NET Core/Blazor

        return builder.Build();
    }
}

  1. ContentPage and XAML: similarities with WPF

A MAUI screen is a ContentPage, the mobile equivalent of a WPF Window, and its XAML uses an almost identical syntax:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="BiblioTech.Mobile.MainPage">

    <StackLayout Padding="20">
        <Label Text="BiblioTech Catalog" FontSize="20" FontAttributes="Bold" />
        <CollectionView x:Name="catalogCollectionView" />
    </StackLayout>

</ContentPage>
WPF .NET MAUI Equivalence
Window ContentPage The screen's root container
StackPanel StackLayout Stacks children vertically or horizontally
TextBlock Label Non-editable text
ListBox/ListView CollectionView List of items, with ItemsSource data binding
{Binding ...} {Binding ...} Same data binding syntax
x:Class, x:Name x:Class, x:Name Same attributes from XAML's x: namespace

Anyone who already knows WPF recognizes the structure immediately: a layout container, child controls, and bindings with the same {Binding PropertyName} syntax. The MVVM pattern (ViewModel, INotifyPropertyChanged) introduced in the WPF lesson applies to MAUI in exactly the same way, with no new concept to learn on that front.

  1. Complete example: a BiblioTech catalog screen with CollectionView

Reusing the CatalogViewModel from the WPF lesson almost unchanged (same properties, same ICommand), the MAUI screen:

<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="BiblioTech.Mobile.MainPage">

    <StackLayout Padding="20">
        <Label Text="BiblioTech Catalog" FontSize="20" FontAttributes="Bold" />

        <CollectionView ItemsSource="{Binding Catalog}"
                         SelectionMode="Single"
                         SelectedItem="{Binding SelectedItem}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Orientation="Horizontal" Padding="0,5">
                        <Label Text="{Binding Title}" FontAttributes="Bold" WidthRequest="200" />
                        <Label Text="{Binding Author}" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

        <Button Text="Lend" Command="{Binding LendCommand}" Margin="0,10,0,0" />

        <Label Text="{Binding StatusMessage}" Margin="0,10,0,0" />
    </StackLayout>

</ContentPage>
// MainPage.xaml.cs (code-behind, just as minimal as in WPF)
public partial class MainPage : ContentPage
{
    public MainPage(Library library)
    {
        InitializeComponent();
        BindingContext = new CatalogViewModel(library); // equivalent to DataContext in WPF
    }
}

CollectionView.ItemTemplate/DataTemplate defines how each item of the list is drawn — here, a row with the title in bold and the author next to it — something that in WPF would be solved equivalently with ItemTemplate on a ListBox or ListView. BindingContext is, in MAUI, the name of the property equivalent to DataContext in WPF: both indicate which object the view's {Binding ...} refer to. CatalogViewModel itself — with Catalog, SelectedItem, LendCommand, and StatusMessage — is exactly the same class written in the WPF lesson, with no modification at all: the very same C# class works, unchanged, in both a desktop window and a mobile screen.

  1. Closing out Module 7 and the link to Module 8

This lesson closes out Module 7's tour of the main ways to give BiblioTech an interface: desktop with Windows Forms and WPF, web with ASP.NET Core and Blazor, and cross-platform (mobile and desktop) with Xamarin.Forms/.NET MAUI. Across the five lessons, the domain built in the previous modules — LibraryItem, Book, Magazine, Member, Loan, Library — hasn't changed by a single line: each technology has simply added a different presentation layer on top of the same core logic.

Module 8 (Best Practices and Design Patterns) now takes all that code built throughout the course — the domain, the persistence, and this module's five interfaces — and puts it under review: coding standards, classic design patterns, dependency injection in depth (the mechanism only mentioned in passing here, in ASP.NET Core, Blazor, and MAUI), unit testing, and refactoring. It's the module where BiblioTech stops growing in functionality and starts being polished in quality.

Common Mistakes and Tips

  • Treating Xamarin.Forms as if it were interchangeable with .NET MAUI with no changes at all: even though they share a philosophy and a very similar XAML syntax, MAUI reorganizes the project's structure (a single cross-platform project, instead of several) and changes internal namespaces and APIs; migrating a real Xamarin.Forms project requires following the official migration guide, it isn't a simple template swap.
  • Starting a new mobile project in Xamarin.Forms in 2026: since it's the predecessor already officially replaced, any new project should start directly from .NET MAUI, which is where active development and support are.
  • Forgetting that MAUI also covers desktop (Windows, macOS), not just mobile: it's common to think of MAUI purely as "Xamarin for mobile," when in reality its range of target platforms is broader, including the same desktop platforms that WPF or Windows Forms cover separately.
  • Tip: if you already know WPF (previous lesson), build on that foundation when learning MAUI: most concepts (XAML, data binding, MVVM, ICommand) transfer almost directly, only the specific names of some controls change (StackPanelStackLayout, TextBlockLabel).

Exercises

  1. Complete the equivalence table from section 5 by adding a row for Button (identical in both frameworks) and another for Grid (also available in both, with the same row/column syntax).

  2. Explain, in a short paragraph, why the same CatalogViewModel from the WPF lesson can be reused unchanged in this lesson's MAUI screen, and which design principle (already seen in the WPF lesson) makes that possible.

Solutions

WPF .NET MAUI Equivalence
Button Button Same name and main properties (Content/Text, Command) in both
Grid Grid Same name; rows/columns defined with RowDefinitions/ColumnDefinitions in both

CatalogViewModel doesn't know or depend on any specific visual control: it only exposes properties (Catalog, SelectedItem, StatusMessage) and a command (LendCommand), communicating with the view exclusively through INotifyPropertyChanged and ICommand. That is precisely the separation the MVVM pattern enforces: the view (whether a WPF Window or a MAUI ContentPage) is the only part that changes between platforms; the ViewModel, knowing nothing about specific controls, is independent of the interface technology and can be reused as is.

Conclusion

In this lesson you've seen Xamarin.Forms's historical role in cross-platform mobile development with C#, why .NET MAUI replaces it as its official evolution — unifying mobile and desktop into a single project integrated into .NET — and you've built a MAUI screen that reuses, unchanged, the very same CatalogViewModel from the WPF lesson thanks to the separation MVVM enforces. With ContentPage, CollectionView, and XAML almost identical to WPF's, BiblioTech now has a presence on desktop, web, and mobile devices, always on top of the same domain built since Module 2.

This closes out Module 7 (Building Applications) in full. Module 8 (Best Practices and Design Patterns) now picks up all the accumulated code — the domain, the persistence, and this module's five interfaces — to polish it: coding standards, design patterns, dependency injection in depth, unit testing, and review and refactoring, closing the cycle before the Final Project in Module 9.

© Copyright 2026. All rights reserved