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
- Xamarin.Forms: el seu paper històric en el desenvolupament mòbil amb C#
- Per què Microsoft va substituir Xamarin.Forms per .NET MAUI
- Què guanya un projecte amb .NET MAUI: un únic projecte multiplataforma
- Estructura bàsica d'un projecte MAUI
ContentPagei XAML: semblances amb WPF- Exemple complet: pantalla de catàleg de BiblioTech amb
CollectionView - Tancament del Mòdul 7 i enllaç amb el Mòdul 8
- 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.
- 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.
- 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ó.
- Estructura bàsica d'un projecte MAUI
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();
}
}
ContentPage i XAML: semblances amb WPF
ContentPage i XAML: semblances amb WPFUna 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.
- Exemple complet: pantalla de catàleg de BiblioTech amb
CollectionView
CollectionViewReutilitzant 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.
- 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 (StackPanel→StackLayout,TextBlock→Label).
Exercicis
-
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 aGrid(disponible també en tots dos, amb la mateixa sintaxi de files i columnes). -
Explica, en un paràgraf breu, per què el mateix
CatalegViewModelde 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#
- Introducció al C#
- Configuració de l'Entorn de Desenvolupament
- Programa Hola Món
- Sintaxi i Estructura Bàsica
- Variables i Tipus de Dades
- Arrays i Cadenes de Text
Mòdul 2: Estructures de Control
Mòdul 3: Programació Orientada a Objectes
- Classes i Objectes
- Mètodes
- Constructors i Destructors
- Herència
- Polimorfisme
- Encapsulació
- Abstracció
- Structs i Records: Tipus per Valor i per Referència
Mòdul 4: Conceptes Avançats de C#
- Interfícies
- Delegats i Esdeveniments
- Pattern Matching i Característiques Modernes de C#
- Genèrics
- Col·leccions
- LINQ (Consulta Integrada en el Llenguatge)
- Programació Asíncrona
Mòdul 5: Treballant amb Dades
- Entrada/Sortida de Fitxers
- Serialització
- Connectivitat amb Bases de Dades
- Entity Framework
- Treball amb JSON i Consum d'APIs REST
Mòdul 6: Temes Avançats
- Reflexió
- Atributs
- Programació Dinàmica
- Gestió de Memòria i Recollida d'Escombraries
- Multifil i Programació Paral·lela
Mòdul 7: Construcció d'Aplicacions
Mòdul 8: Bones Pràctiques i Patrons de Disseny
- Estàndards de Codificació i Bones Pràctiques
- Patrons de Disseny
- Injecció de Dependències i Inversió de Control
- Proves Unitàries
- Revisió i Refactorització de Codi
