Las cuatro lecciones anteriores llevaron BiblioTech al escritorio (Windows Forms, WPF) y a la web (ASP.NET Core, Blazor). Queda una plataforma por cubrir: los dispositivos móviles. Esta última lección del Módulo 7 presenta Xamarin.Forms, el framework que durante años permitió escribir aplicaciones móviles multiplataforma en C#, y su sucesor oficial, .NET MAUI (Multi platform App UI), hacia el que Microsoft ha migrado todo el ecosistema. Verás por qué existió ese cambio, qué gana un proyecto al adoptar MAUI, y construirás una pantalla móvil sencilla que muestra el catálogo de BiblioTech, con un XAML que te resultará muy familiar tras la lección de WPF. Con esto se cierra el recorrido del Módulo 7 por las principales formas de dar interfaz a una aplicación C#.
Contenido
- Xamarin.Forms: su papel histórico en el desarrollo móvil con C#
- Por qué Microsoft sustituyó Xamarin.Forms por .NET MAUI
- Qué gana un proyecto con .NET MAUI: un único proyecto multiplataforma
- Estructura básica de un proyecto MAUI
ContentPagey XAML: similitudes con WPF- Ejemplo completo: pantalla de catálogo de BiblioTech con
CollectionView - Cierre del Módulo 7 y enlace con el Módulo 8
- Xamarin.Forms: su papel histórico en el desarrollo móvil con C#
Antes de Xamarin, desarrollar una aplicación para Android exigía Java o Kotlin, y para iOS, Objective-C o Swift: dos bases de código completamente separadas, con dos equipos o el doble de esfuerzo para la misma aplicación. Xamarin, adquirido por Microsoft en 2016, permitió escribir esa lógica en C# y compilarla de forma nativa para ambas plataformas; Xamarin.Forms, en concreto, añadió además una capa de interfaz compartida en XAML, de modo que ni siquiera la interfaz visual tuviera que escribirse dos veces.
Durante varios años, Xamarin.Forms fue la vía principal de Microsoft para desarrollo móvil
multiplataforma en C#, y muchísimas aplicaciones en producción todavía funcionan sobre él. Es
importante reconocerlo si te encuentras con código Xamarin.Forms existente: la sintaxis XAML y
los conceptos de ContentPage que verás en esta lección son, en gran medida, los mismos que
introdujo Xamarin.Forms en su momento.
- Por qué Microsoft sustituyó Xamarin.Forms por .NET MAUI
Microsoft anunció el fin del soporte de Xamarin.Forms y su evolución hacia .NET MAUI como sucesor oficial, integrado directamente en .NET (a partir de .NET 6), en vez de mantenerse como un framework separado con su propio ciclo de vida. Las razones principales de este cambio:
| Limitación de Xamarin.Forms | Cómo lo resuelve .NET MAUI |
|---|---|
| Proyecto separado del resto del ecosistema .NET, con herramientas y ciclo de versiones propios | Integrado en .NET desde su base: mismo SDK, mismo dotnet new, mismas versiones que el resto del curso |
| Un proyecto por plataforma (Android, iOS) con configuración duplicada | Un único proyecto multiplataforma (apartado 3) |
| Sin soporte nativo para aplicaciones de escritorio (Windows, macOS) | Soporte de escritorio incluido desde el diseño inicial |
| Arquitectura de renderizado más antigua, con más capas intermedias | Arquitectura de handlers más directa y con mejor rendimiento |
.NET MAUI no es, por tanto, un framework nuevo sin relación con Xamarin.Forms: es su evolución/sucesor oficial, pensado para resolver precisamente esas limitaciones de arquitectura y unificar el desarrollo móvil dentro del mismo .NET que ya usas en el resto de este curso. Un proyecto Xamarin.Forms existente puede migrarse a .NET MAUI (Microsoft documenta ese camino), pero para un proyecto nuevo en 2026, la elección natural es directamente MAUI.
- Qué gana un proyecto con .NET MAUI: un único proyecto multiplataforma
La ganancia más visible de MAUI frente al Xamarin.Forms original es la unificación: un solo
proyecto .csproj compila para varias plataformas de destino, sin mantener proyectos separados:
flowchart TD
P["Un unico proyecto .NET MAUI<br/>(BiblioTech.Movil)"] --> A["Android"]
P --> I["iOS"]
P --> W["Windows"]
P --> M["macOS (Mac Catalyst)"]
Además, ese mismo proyecto puede compartir la interfaz XAML con un proyecto WPF de escritorio
—la sintaxis básica de controles y binding es muy similar entre WPF y MAUI, como se verá en el
apartado 5—, y por supuesto puede referenciar directamente las clases de dominio de BiblioTech ya
existentes (Biblioteca, Libro, Socio...), sin ninguna adaptación.
- Estructura básica de un proyecto MAUI
BiblioTech.Movil/
├── MauiProgram.cs
├── App.xaml
├── App.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
└── Platforms/
├── Android/
├── iOS/
├── Windows/
└── MacCatalyst/MauiProgram.cs: el punto de arranque de la aplicación, donde se configura el contenedor de servicios —el mismo mecanismo de inyección de dependencias visto en ASP.NET Core y Blazor—.App.xaml/App.xaml.cs: la aplicación en sí, que decide qué página mostrar al arrancar.MainPage.xaml/.xaml.cs: la primera pantalla, con el mismo patrón XAML + code-behind ya conocido de WPF.Platforms/: código específico de cada plataforma (iconos nativos, permisos...), que rara vez hace falta tocar para una aplicación sencilla como la de esta lección.
// MauiProgram.cs (fragmento)
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>();
builder.Services.AddSingleton<Biblioteca>(); // mismo contenedor de servicios que ASP.NET Core/Blazor
return builder.Build();
}
}
ContentPage y XAML: similitudes con WPF
ContentPage y XAML: similitudes con WPFUna pantalla MAUI es una ContentPage, el equivalente móvil de un Window de WPF, y su XAML usa
una sintaxis casi idéntica:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BiblioTech.Movil.MainPage">
<StackLayout Padding="20">
<Label Text="Catalogo de BiblioTech" FontSize="20" FontAttributes="Bold" />
<CollectionView x:Name="listaCatalogo" />
</StackLayout>
</ContentPage>| WPF | .NET MAUI | Equivalencia |
|---|---|---|
Window |
ContentPage |
Contenedor raíz de la pantalla |
StackPanel |
StackLayout |
Apila hijos vertical u horizontalmente |
TextBlock |
Label |
Texto no editable |
ListBox/ListView |
CollectionView |
Lista de elementos, con data binding de ItemsSource |
{Binding ...} |
{Binding ...} |
Misma sintaxis de data binding |
x:Class, x:Name |
x:Class, x:Name |
Mismos atributos del espacio de nombres x: de XAML |
Quien ya conoce WPF reconoce inmediatamente la estructura: un contenedor de layout, controles
hijos, y bindings con la misma sintaxis {Binding NombrePropiedad}. El patrón MVVM (ViewModel,
INotifyPropertyChanged) introducido en la lección de WPF se aplica en MAUI exactamente igual,
sin ningún concepto nuevo que aprender en ese frente.
- Ejemplo completo: pantalla de catálogo de BiblioTech con
CollectionView
CollectionViewReutilizando el CatalogoViewModel de la lección de WPF casi sin cambios (mismas propiedades,
mismo 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.Movil.MainPage">
<StackLayout Padding="20">
<Label Text="Catalogo de BiblioTech" FontSize="20" FontAttributes="Bold" />
<CollectionView ItemsSource="{Binding Catalogo}"
SelectionMode="Single"
SelectedItem="{Binding MaterialSeleccionado}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Padding="0,5">
<Label Text="{Binding Titulo}" FontAttributes="Bold" WidthRequest="200" />
<Label Text="{Binding Autor}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button Text="Prestar" Command="{Binding ComandoPrestar}" Margin="0,10,0,0" />
<Label Text="{Binding MensajeEstado}" Margin="0,10,0,0" />
</StackLayout>
</ContentPage>// MainPage.xaml.cs (code-behind, igual de minimo que en WPF)
public partial class MainPage : ContentPage
{
public MainPage(Biblioteca biblioteca)
{
InitializeComponent();
BindingContext = new CatalogoViewModel(biblioteca); // equivalente a DataContext en WPF
}
}CollectionView.ItemTemplate/DataTemplate define cómo se dibuja cada elemento de la lista
—aquí, una fila con el título en negrita y el autor al lado—, algo que en WPF se resolvería de
forma equivalente con ItemTemplate sobre un ListBox o ListView. BindingContext es, en
MAUI, el nombre de la propiedad equivalente a DataContext en WPF: ambas indican a qué objeto se
refieren los {Binding ...} de la vista. El CatalogoViewModel en sí —con Catalogo,
MaterialSeleccionado, ComandoPrestar y MensajeEstado— es exactamente el mismo escrito en la
lección de WPF, sin ninguna modificación: la misma clase de C# funciona, sin cambios, tanto en
una ventana de escritorio como en una pantalla móvil.
- Cierre del Módulo 7 y enlace con el Módulo 8
Con esta lección se cierra el recorrido del Módulo 7 por las principales formas de dar interfaz a
BiblioTech: escritorio con Windows Forms y WPF, web con ASP.NET Core y Blazor, y multiplataforma
(móvil y escritorio) con Xamarin.Forms/.NET MAUI. En las cinco lecciones, el dominio construido
en los módulos anteriores —MaterialBibliotecario, Libro, Revista, Socio, Prestamo,
Biblioteca— no ha cambiado ni una sola línea: cada tecnología se ha limitado a añadir una capa
de presentación distinta encima del mismo núcleo de lógica.
El Módulo 8 (Mejores Prácticas y Patrones de Diseño) toma ahora todo ese código construido a lo largo del curso —dominio, persistencia, y las cinco interfaces de este módulo— y lo somete a revisión: estándares de codificación, patrones de diseño clásicos, inyección de dependencias en profundidad (el mecanismo que aquí solo se ha mencionado de pasada, en ASP.NET Core, Blazor y MAUI), pruebas unitarias, y refactorización. Es el módulo donde BiblioTech deja de crecer en funcionalidad y empieza a pulirse en calidad.
Errores Comunes y Consejos
- Tratar Xamarin.Forms como si fuera intercambiable con .NET MAUI sin ningún cambio: aunque comparten filosofía y una sintaxis XAML muy parecida, MAUI reorganiza la estructura del proyecto (un único proyecto multiplataforma, en vez de varios) y cambia espacios de nombres y APIs internas; migrar un proyecto Xamarin.Forms real requiere seguir la guía oficial de migración, no es un simple cambio de plantilla.
- Empezar un proyecto móvil nuevo en Xamarin.Forms en 2026: al ser el predecesor ya sustituido oficialmente, cualquier proyecto nuevo debería partir directamente de .NET MAUI, que es donde está el desarrollo y el soporte activos.
- Olvidar que MAUI también cubre escritorio (Windows, macOS), no solo móvil: es habitual pensar en MAUI únicamente como "Xamarin para móvil", cuando en realidad su ámbito de plataformas de destino es más amplio, incluyendo las mismas plataformas de escritorio que WPF o Windows Forms cubren por separado.
- Consejo: si ya conoces WPF (lección anterior), aprovecha esa base al aprender MAUI: la
mayoría de conceptos (XAML, data binding, MVVM,
ICommand) se transfieren casi directamente, cambiando solo los nombres concretos de algunos controles (StackPanel→StackLayout,TextBlock→Label).
Ejercicios
-
Completa la tabla de equivalencias del apartado 5 añadiendo una fila para
Button(idéntico en ambos frameworks) y otra paraGrid(disponible también en ambos, con la misma sintaxis de filas y columnas). -
Explica, en un párrafo breve, por qué el mismo
CatalogoViewModelde la lección de WPF puede reutilizarse sin cambios en la pantalla MAUI de esta lección, y qué principio de diseño (visto ya en la lección de WPF) lo hace posible.
Soluciones
| WPF | .NET MAUI | Equivalencia |
|---|---|---|
Button |
Button |
Mismo nombre y propiedades principales (Content/Text, Command) en ambos |
Grid |
Grid |
Mismo nombre; filas/columnas definidas con RowDefinitions/ColumnDefinitions en ambos |
El CatalogoViewModel no conoce ni depende de ningún control visual concreto: solo expone
propiedades (Catalogo, MaterialSeleccionado, MensajeEstado) y un comando
(ComandoPrestar), comunicándose con la vista exclusivamente mediante INotifyPropertyChanged
e ICommand. Esa es precisamente la separación que impone el patrón MVVM: la vista (sea
una Window de WPF o una ContentPage de MAUI) es la única parte que cambia entre
plataformas; el ViewModel, al no saber nada de controles concretos, es independiente de la
tecnología de interfaz y puede reutilizarse tal cual.
Conclusión
En esta lección has visto el papel histórico de Xamarin.Forms en el desarrollo móvil
multiplataforma con C#, por qué .NET MAUI lo sustituye como su evolución oficial —unificando
móvil y escritorio en un único proyecto integrado en .NET—, y has construido una pantalla MAUI
que reutiliza, sin cambios, el mismo CatalogoViewModel de la lección de WPF gracias a la
separación que impone MVVM. Con ContentPage, CollectionView y un XAML casi idéntico al de
WPF, BiblioTech tiene ya presencia en escritorio, web y dispositivos móviles, siempre sobre el
mismo dominio construido desde el Módulo 2.
Con esto se cierra el Módulo 7 (Construcción de Aplicaciones) al completo. El Módulo 8 (Mejores Prácticas y Patrones de Diseño) retoma ahora todo el código acumulado —dominio, persistencia, y las cinco interfaces de este módulo— para pulirlo: estándares de codificación, patrones de diseño, inyección de dependencias en profundidad, pruebas unitarias, y revisión y refactorización, cerrando el ciclo antes del Proyecto Final del Módulo 9.
Curso de Programación en C#
Módulo 1: Introducción a C#
- Introducción a C#
- Configuración del Entorno de Desarrollo
- Programa Hola Mundo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Arrays y Cadenas de Texto
Módulo 2: Estructuras de Control
Módulo 3: Programación Orientada a Objetos
- Clases y Objetos
- Métodos
- Constructores y Destructores
- Herencia
- Polimorfismo
- Encapsulamiento
- Abstracción
- Structs y Records: Tipos por Valor y por Referencia
Módulo 4: Conceptos Avanzados de C#
- Interfaces
- Delegados y Eventos
- Pattern Matching y Características Modernas de C#
- Genéricos
- Colecciones
- LINQ (Consulta Integrada en el Lenguaje)
- Programación Asíncrona
Módulo 5: Trabajando con Datos
- Entrada/Salida de Archivos
- Serialización
- Conectividad con Bases de Datos
- Entity Framework
- Trabajo con JSON y Consumo de APIs REST
Módulo 6: Temas Avanzados
- Reflexión
- Atributos
- Programación Dinámica
- Gestión de Memoria y Recolección de Basura
- Multihilo y Programación Paralela
Módulo 7: Construcción de Aplicaciones
- Formularios de Windows
- WPF (Windows Presentation Foundation)
- ASP.NET Core
- Blazor
- Xamarin y .NET MAUI
Módulo 8: Mejores Prácticas y Patrones de Diseño
- Estándares de Codificación y Mejores Prácticas
- Patrones de Diseño
- Inyección de Dependencias e Inversión de Control
- Pruebas Unitarias
- Revisión y Refactorización de Código
