Les quatre lliçons anteriors van portar BiblioTech a l'escriptori (Windows Forms, WPF) i a la web (ASP.NET Core, Blazor). Queda una plataforma per cobrir: els dispositius mòbils. Aquesta última lliçó del Mòdul 7 presenta Xamarin.Forms, el framework que durant anys va permetre escriure aplicacions mòbils multiplataforma en C#, i el seu successor oficial, .NET MAUI (Multi platform App UI), cap al qual Microsoft ha migrat tot l'ecosistema. Veuràs per què va existir aquest canvi, què guanya un projecte en adoptar MAUI, i construiràs una pantalla mòbil senzilla que mostra el catàleg de BiblioTech, amb un XAML que et resultarà molt familiar després de la lliçó de WPF. Amb això es tanca el recorregut del Mòdul 7 per les principals formes de donar interfície a una aplicació C#.

Contingut

  1. Xamarin.Forms: el seu paper històric en el desenvolupament mòbil amb C#
  2. Per què Microsoft va substituir Xamarin.Forms per .NET MAUI
  3. Què guanya un projecte amb .NET MAUI: un únic projecte multiplataforma
  4. Estructura bàsica d'un projecte MAUI
  5. ContentPage i XAML: semblances amb WPF
  6. Exemple complet: pantalla de catàleg de BiblioTech amb CollectionView
  7. Tancament del Mòdul 7 i enllaç amb el Mòdul 8

  1. Xamarin.Forms: el seu paper històric en el desenvolupament mòbil amb C#

Abans de Xamarin, desenvolupar una aplicació per a Android exigia Java o Kotlin, i per a iOS, Objective-C o Swift: dues bases de codi completament separades, amb dos equips o el doble d'esforç per a la mateixa aplicació. Xamarin, adquirit per Microsoft el 2016, va permetre escriure aquesta lògica en C# i compilar-la de forma nativa per a totes dues plataformes; Xamarin.Forms, en concret, va afegir a més una capa d'interfície compartida en XAML, de manera que ni tan sols la interfície visual s'hagués d'escriure dues vegades.

Durant diversos anys, Xamarin.Forms va ser la via principal de Microsoft per al desenvolupament mòbil multiplataforma en C#, i moltíssimes aplicacions en producció encara funcionen sobre ell. És important reconèixer-ho si et trobes amb codi Xamarin.Forms existent: la sintaxi XAML i els conceptes de ContentPage que veuràs en aquesta lliçó són, en gran mesura, els mateixos que va introduir Xamarin.Forms en el seu moment.

  1. Per què Microsoft va substituir Xamarin.Forms per .NET MAUI

Microsoft va anunciar la fi del suport de Xamarin.Forms i la seva evolució cap a .NET MAUI com a successor oficial, integrat directament a .NET (a partir de .NET 6), en lloc de mantenir-se com un framework separat amb el seu propi cicle de vida. Les raons principals d'aquest canvi:

Limitació de Xamarin.Forms Com ho resol .NET MAUI
Projecte separat de la resta de l'ecosistema .NET, amb eines i cicle de versions propis Integrat a .NET des de la base: mateix SDK, mateix dotnet new, mateixes versions que la resta del curs
Un projecte per plataforma (Android, iOS) amb configuració duplicada Un únic projecte multiplataforma (apartat 3)
Sense suport natiu per a aplicacions d'escriptori (Windows, macOS) Suport d'escriptori inclòs des del disseny inicial
Arquitectura de renderitzat més antiga, amb més capes intermèdies Arquitectura de handlers més directa i amb millor rendiment

.NET MAUI no és, per tant, un framework nou sense relació amb Xamarin.Forms: és la seva evolució/successor oficial, pensat per resoldre precisament aquestes limitacions d'arquitectura i unificar el desenvolupament mòbil dins del mateix .NET que ja fas servir a la resta d'aquest curs. Un projecte Xamarin.Forms existent es pot migrar a .NET MAUI (Microsoft documenta aquest camí), però per a un projecte nou el 2026, l'elecció natural és directament MAUI.

  1. Què guanya un projecte amb .NET MAUI: un únic projecte multiplataforma

El guany més visible de MAUI davant el Xamarin.Forms original és la unificació: un sol projecte .csproj compila per a diverses plataformes de destí, sense mantenir projectes separats:

flowchart TD
    P["Un unic projecte .NET MAUI<br/>(BiblioTech.Mobil)"] --> A["Android"]
    P --> I["iOS"]
    P --> W["Windows"]
    P --> M["macOS (Mac Catalyst)"]

A més, aquest mateix projecte pot compartir la interfície XAML amb un projecte WPF d'escriptori —la sintaxi bàsica de controls i binding és molt semblant entre WPF i MAUI, com es veurà a l'apartat 5—, i per descomptat pot referenciar directament les classes de domini de BiblioTech ja existents (Biblioteca, Llibre, Soci...), sense cap adaptació.

  1. Estructura bàsica d'un projecte MAUI

dotnet new maui -n BiblioTech.Mobil
BiblioTech.Mobil/
├── MauiProgram.cs
├── App.xaml
├── App.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
└── Platforms/
    ├── Android/
    ├── iOS/
    ├── Windows/
    └── MacCatalyst/
  • MauiProgram.cs: el punt d'arrencada de l'aplicació, on es configura el contenidor de serveis —el mateix mecanisme d'injecció de dependències vist a ASP.NET Core i Blazor—.
  • App.xaml/App.xaml.cs: l'aplicació en si, que decideix quina pàgina mostrar en arrencar.
  • MainPage.xaml/.xaml.cs: la primera pantalla, amb el mateix patró XAML + code-behind ja conegut de WPF.
  • Platforms/: codi específic de cada plataforma (icones natives, permisos...), que rarament cal tocar per a una aplicació senzilla com la d'aquesta lliçó.
// MauiProgram.cs (fragment)
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        builder.Services.AddSingleton<Biblioteca>(); // mateix contenidor de serveis que ASP.NET Core/Blazor

        return builder.Build();
    }
}

  1. ContentPage i XAML: semblances amb WPF

Una pantalla MAUI és una ContentPage, l'equivalent mòbil d'un Window de WPF, i el seu XAML fa servir una sintaxi gairebé idèntica:

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

    <StackLayout Padding="20">
        <Label Text="Cataleg de BiblioTech" FontSize="20" FontAttributes="Bold" />
        <CollectionView x:Name="llistaCataleg" />
    </StackLayout>

</ContentPage>
WPF .NET MAUI Equivalència
Window ContentPage Contenidor arrel de la pantalla
StackPanel StackLayout Apila fills vertical o horitzontalment
TextBlock Label Text no editable
ListBox/ListView CollectionView Llista d'elements, amb data binding d'ItemsSource
{Binding ...} {Binding ...} Mateixa sintaxi de data binding
x:Class, x:Name x:Class, x:Name Mateixos atributs de l'espai de noms x: de XAML

Qui ja coneix WPF reconeix immediatament l'estructura: un contenidor de layout, controls fills, i bindings amb la mateixa sintaxi {Binding NomPropietat}. El patró MVVM (ViewModel, INotifyPropertyChanged) introduït a la lliçó de WPF s'aplica a MAUI exactament igual, sense cap concepte nou a aprendre en aquest front.

  1. Exemple complet: pantalla de catàleg de BiblioTech amb CollectionView

Reutilitzant el CatalegViewModel de la lliçó de WPF gairebé sense canvis (mateixes propietats, mateix ICommand), la pantalla MAUI:

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

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

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

        <Button Text="Prestar" Command="{Binding ComandamentPrestar}" Margin="0,10,0,0" />

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

</ContentPage>
// MainPage.xaml.cs (code-behind, igual de minim que a WPF)
public partial class MainPage : ContentPage
{
    public MainPage(Biblioteca biblioteca)
    {
        InitializeComponent();
        BindingContext = new CatalegViewModel(biblioteca); // equivalent a DataContext a WPF
    }
}

CollectionView.ItemTemplate/DataTemplate defineix com es dibuixa cada element de la llista —aquí, una fila amb el títol en negreta i l'autor al costat—, una cosa que a WPF es resoldria de forma equivalent amb ItemTemplate sobre un ListBox o ListView. BindingContext és, a MAUI, el nom de la propietat equivalent a DataContext a WPF: totes dues indiquen a quin objecte es refereixen els {Binding ...} de la vista. El CatalegViewModel en si —amb Cataleg, MaterialSeleccionat, ComandamentPrestar i MissatgeEstat— és exactament el mateix escrit a la lliçó de WPF, sense cap modificació: la mateixa classe de C# funciona, sense canvis, tant en una finestra d'escriptori com en una pantalla mòbil.

  1. Tancament del Mòdul 7 i enllaç amb el Mòdul 8

Amb aquesta lliçó es tanca el recorregut del Mòdul 7 per les principals formes de donar interfície a BiblioTech: escriptori amb Windows Forms i WPF, web amb ASP.NET Core i Blazor, i multiplataforma (mòbil i escriptori) amb Xamarin.Forms/.NET MAUI. En les cinc lliçons, el domini construït en els mòduls anteriors —MaterialBibliotecari, Llibre, Revista, Soci, Prestec, Biblioteca— no ha canviat ni una sola línia: cada tecnologia s'ha limitat a afegir una capa de presentació diferent a sobre del mateix nucli de lògica.

El Mòdul 8 (Bones Pràctiques i Patrons de Disseny) pren ara tot aquest codi construït al llarg del curs —domini, persistència, i les cinc interfícies d'aquest mòdul— i el sotmet a revisió: estàndards de codificació, patrons de disseny clàssics, injecció de dependències en profunditat (el mecanisme que aquí només s'ha mencionat de passada, a ASP.NET Core, Blazor i MAUI), proves unitàries, i refactorització. És el mòdul on BiblioTech deixa de créixer en funcionalitat i comença a polir-se en qualitat.

Errors Comuns i Consells

  • Tractar Xamarin.Forms com si fos intercanviable amb .NET MAUI sense cap canvi: tot i que comparteixen filosofia i una sintaxi XAML molt semblant, MAUI reorganitza l'estructura del projecte (un únic projecte multiplataforma, en lloc de diversos) i canvia espais de noms i APIs internes; migrar un projecte Xamarin.Forms real requereix seguir la guia oficial de migració, no és un simple canvi de plantilla.
  • Començar un projecte mòbil nou en Xamarin.Forms el 2026: en ser el predecessor ja substituït oficialment, qualsevol projecte nou hauria de partir directament de .NET MAUI, que és on hi ha el desenvolupament i el suport actius.
  • Oblidar que MAUI també cobreix escriptori (Windows, macOS), no només mòbil: és habitual pensar en MAUI únicament com "Xamarin per a mòbil", quan en realitat el seu àmbit de plataformes de destí és més ampli, incloent les mateixes plataformes d'escriptori que WPF o Windows Forms cobreixen per separat.
  • Consell: si ja coneixes WPF (lliçó anterior), aprofita aquesta base en aprendre MAUI: la majoria de conceptes (XAML, data binding, MVVM, ICommand) es transfereixen gairebé directament, canviant només els noms concrets d'alguns controls (StackPanelStackLayout, TextBlockLabel).

Exercicis

  1. Completa la taula d'equivalències de l'apartat 5 afegint una fila per a Button (idèntic en tots dos frameworks) i una altra per a Grid (disponible també en tots dos, amb la mateixa sintaxi de files i columnes).

  2. Explica, en un paràgraf breu, per què el mateix CatalegViewModel de la lliçó de WPF es pot reutilitzar sense canvis a la pantalla MAUI d'aquesta lliçó, i quin principi de disseny (vist ja a la lliçó de WPF) ho fa possible.

Solucions

WPF .NET MAUI Equivalència
Button Button Mateix nom i propietats principals (Content/Text, Command) en tots dos
Grid Grid Mateix nom; files/columnes definides amb RowDefinitions/ColumnDefinitions en tots dos

El CatalegViewModel no coneix ni depèn de cap control visual concret: només exposa propietats (Cataleg, MaterialSeleccionat, MissatgeEstat) i un comandament (ComandamentPrestar), comunicant-se amb la vista exclusivament mitjançant INotifyPropertyChanged i ICommand. Aquesta és precisament la separació que imposa el patró MVVM: la vista (sigui una Window de WPF o una ContentPage de MAUI) és l'única part que canvia entre plataformes; el ViewModel, en no saber res de controls concrets, és independent de la tecnologia d'interfície i es pot reutilitzar tal qual.

Conclusió

En aquesta lliçó has vist el paper històric de Xamarin.Forms en el desenvolupament mòbil multiplataforma amb C#, per què .NET MAUI el substitueix com a evolució oficial —unificant mòbil i escriptori en un únic projecte integrat a .NET—, i has construït una pantalla MAUI que reutilitza, sense canvis, el mateix CatalegViewModel de la lliçó de WPF gràcies a la separació que imposa MVVM. Amb ContentPage, CollectionView i un XAML gairebé idèntic al de WPF, BiblioTech ja té presència a escriptori, web i dispositius mòbils, sempre sobre el mateix domini construït des del Mòdul 2.

Amb això es tanca el Mòdul 7 (Construcció d'Aplicacions) al complet. El Mòdul 8 (Bones Pràctiques i Patrons de Disseny) retoma ara tot el codi acumulat —domini, persistència, i les cinc interfícies d'aquest mòdul— per polir-lo: estàndards de codificació, patrons de disseny, injecció de dependències en profunditat, proves unitàries, i revisió i refactorització, tancant el cicle abans del Projecte Final del Mòdul 9.

Curs de Programació en C#

Mòdul 1: Introducció al C#

Mòdul 2: Estructures de Control

Mòdul 3: Programació Orientada a Objectes

Mòdul 4: Conceptes Avançats de C#

Mòdul 5: Treballant amb Dades

Mòdul 6: Temes Avançats

Mòdul 7: Construcció d'Aplicacions

Mòdul 8: Bones Pràctiques i Patrons de Disseny

Mòdul 9: Projecte Final

© Copyright 2026. Tots els drets reservats