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

  1. Xamarin.Forms: su papel histórico en el desarrollo móvil con C#
  2. Por qué Microsoft sustituyó Xamarin.Forms por .NET MAUI
  3. Qué gana un proyecto con .NET MAUI: un único proyecto multiplataforma
  4. Estructura básica de un proyecto MAUI
  5. ContentPage y XAML: similitudes con WPF
  6. Ejemplo completo: pantalla de catálogo de BiblioTech con CollectionView
  7. Cierre del Módulo 7 y enlace con el Módulo 8

  1. 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.

  1. 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.

  1. 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.

  1. Estructura básica de un proyecto MAUI

dotnet new maui -n BiblioTech.Movil
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();
    }
}

  1. ContentPage y XAML: similitudes con WPF

Una 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.

  1. Ejemplo completo: pantalla de catálogo de BiblioTech con CollectionView

Reutilizando 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.

  1. 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 (StackPanelStackLayout, TextBlockLabel).

Ejercicios

  1. Completa la tabla de equivalencias del apartado 5 añadiendo una fila para Button (idéntico en ambos frameworks) y otra para Grid (disponible también en ambos, con la misma sintaxis de filas y columnas).

  2. Explica, en un párrafo breve, por qué el mismo CatalogoViewModel de 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#

Módulo 2: Estructuras de Control

Módulo 3: Programación Orientada a Objetos

Módulo 4: Conceptos Avanzados de C#

Módulo 5: Trabajando con Datos

Módulo 6: Temas Avanzados

Módulo 7: Construcción de Aplicaciones

Módulo 8: Mejores Prácticas y Patrones de Diseño

Módulo 9: Proyecto Final

© Copyright 2026. Todos los derechos reservados