.NET MAUI w 2026: Kompletny Przewodnik po Programowaniu Cross-Platform i Pytania Rekrutacyjne
Poznaj .NET MAUI 10 w 2026 roku - od konfiguracji projektu, przez architekturę handlerów, MVVM z CommunityToolkit, HybridWebView, po migrację z Xamarin i kluczowe pytania rekrutacyjne.

.NET MAUI (Multi-platform App UI) osiągnął pełną dojrzałość produkcyjną wraz z wydaniem .NET 10. Jako wersja z długoterminowym wsparciem (LTS, obsługiwana do listopada 2028 roku), .NET MAUI 10 koncentruje się na jakości i wydajności, dostarczając nowe API takie jak HybridWebView oraz SafeAreaEdges. Ten artykuł przedstawia praktyczny przewodnik po tworzeniu aplikacji cross-platform, omawia architekturę frameworka oraz kluczowe pytania pojawiające się na rozmowach kwalifikacyjnych w 2026 roku.
.NET 10 to wydanie z długoterminowym wsparciem (do listopada 2028). MAUI 10 kładzie nacisk na stabilność i wydajność — jest to najbardziej dojrzałe wydanie MAUI dotychczas. Framework jest teraz dystrybuowany jako workload .NET oraz pakiety NuGet, co umożliwia przypinanie wersji per projekt.
Konfiguracja projektu .NET MAUI 10 od podstaw
Najszybszą drogą do uruchomienia aplikacji MAUI jest wykorzystanie .NET CLI. .NET 10 wprowadza zaktualizowany szablon projektu, który zawiera wsparcie dla .NET Aspire, zapewniając telemetrię i odkrywanie usług.
# Install the MAUI workload (if not already present)
dotnet workload install maui
# Create a new MAUI app
dotnet new maui -n CrossPlatformDemo
cd CrossPlatformDemo
# Run on Android emulator
dotnet build -t:Run -f net10.0-androidStruktura pojedynczego projektu konsoliduje kod specyficzny dla platform w katalogu Platforms/, współdzieląc resztę. Plik MauiProgram.cs pełni rolę composition root — to tutaj rejestruje się serwisy, czcionki i handlery.
using Microsoft.Extensions.Logging;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
// Register services for dependency injection
builder.Services.AddSingleton<IApiService, ApiService>();
builder.Services.AddTransient<MainViewModel>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}Wstrzykiwanie zależności w MAUI stosuje ten sam wzorzec co ASP.NET Core. Serwisy Singleton utrzymują się przez cały czas życia aplikacji, serwisy Transient są tworzone przy każdym żądaniu, natomiast serwisy Scoped — choć dostępne — wymagają ostrożności, ponieważ MAUI nie posiada wbudowanej koncepcji zakresu jak żądania HTTP.
Handlery: architektura renderowania cross-platform
MAUI zastąpiło renderery Xamarin.Forms architekturą handlerów. Handlery mapują każdy kontroler cross-platform na jego natywny odpowiednik poprzez cienką warstwę abstrakcji. Kluczowa różnica polega na tym, że handlery są bezstanowe i oddzielone od widoku wirtualnego, co czyni je szybszymi i łatwiejszymi do dostosowania.
using Microsoft.Maui.Handlers;
public class CustomEntryHandler : EntryHandler
{
protected override void ConnectHandler(MauiAppCompatEditText platformView)
{
base.ConnectHandler(platformView);
// Remove the default underline on Android
platformView.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
// Register in MauiProgram.cs
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<Entry, CustomEntryHandler>();
});W .NET 10 kontrolki Entry i Editor na Androidzie przeszły z AppCompatEditText na MauiAppCompatEditText, dodając natywne wsparcie dla zdarzenia SelectionChanged. Ulepszone handlery CollectionView i CarouselView wprowadzone w .NET 9 są teraz domyślne na iOS i Mac Catalyst.
MVVM z CommunityToolkit.Mvvm: eliminacja kodu boilerplate
Generator kodu źródłowego CommunityToolkit.Mvvm eliminuje około 80% ceremonii MVVM. Koniec z ręczną implementacją INotifyPropertyChanged, koniec z wrapperami komend — atrybuty sterują generowaniem kodu.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class MainViewModel : ObservableObject
{
private readonly IApiService _apiService;
public MainViewModel(IApiService apiService)
{
_apiService = apiService;
}
// Source generator creates the 'Title' property with change notification
[ObservableProperty]
private string _title = string.Empty;
// Source generator creates the 'IsLoading' property
[ObservableProperty]
private bool _isLoading;
// Source generator creates an async ICommand
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
try
{
Title = await _apiService.FetchTitleAsync();
}
finally
{
IsLoading = false;
}
}
}XAML wiąże się bezpośrednio z wygenerowanymi właściwościami i komendami:
<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:CrossPlatformDemo.ViewModels"
x:DataType="vm:MainViewModel">
<VerticalStackLayout Padding="20" Spacing="16">
<Label Text="{Binding Title}"
FontSize="24"
HorizontalOptions="Center" />
<Button Text="Load Data"
Command="{Binding LoadDataCommand}"
IsEnabled="{Binding IsLoading, Converter={StaticResource InverseBoolConverter}}" />
<ActivityIndicator IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}" />
</VerticalStackLayout>
</ContentPage>Atrybut x:DataType włącza kompilowane bindowania, które są szybsze od bindowań opartych na refleksji i generują błędy kompilacji, gdy ścieżka bindowania jest nieprawidłowa.
Gotowy na rozmowy o .NET?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
HybridWebView w .NET 10: łączenie natywnego z webowym
HybridWebView umożliwia osadzanie treści webowych wewnątrz aplikacji MAUI przy zachowaniu dwukierunkowej komunikacji między C# a JavaScript. .NET 10 dodaje trzy możliwości: wywołania JavaScript typu fire-and-forget, zdarzenia inicjalizacji dla konfiguracji specyficznej dla platformy oraz przechwytywanie żądań webowych.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Initialization event for platform-specific tweaks
hybridWebView.WebViewInitialized += (sender, args) =>
{
// Access the native platform view after initialization
System.Diagnostics.Debug.WriteLine("WebView ready");
};
}
// Call JavaScript from C#
private async void OnCallJsClicked(object sender, EventArgs e)
{
var result = await hybridWebView.InvokeJavaScriptAsync<string>(
"getFormData", // JS function name
HybridSampleContext.Default.String // JSON serialization context
);
await DisplayAlert("Result", result, "OK");
}
// Fire-and-forget: no return type needed (.NET 10)
private async void OnResetClicked(object sender, EventArgs e)
{
await hybridWebView.InvokeJavaScriptAsync("resetForm");
}
}Odpowiadający JavaScript odbiera wywołania i może wysyłać wiadomości z powrotem do C#:
function getFormData() {
return JSON.stringify({
name: document.getElementById('name').value,
email: document.getElementById('email').value
});
}
function resetForm() {
document.getElementById('name').value = '';
document.getElementById('email').value = '';
}Wyjątki JavaScript rzucane podczas InvokeJavaScriptAsync są teraz automatycznie przekazywane do .NET jako wyjątki, eliminując ciche awarie.
SafeAreaEdges: perfekcyjne układy na każdym urządzeniu
.NET MAUI 10 wprowadza właściwość SafeAreaEdges dla Layout, ContentView, ContentPage, Border i ScrollView. Nowy enum (None, SoftInput, Container, Default, All) zastępuje starsze podejście Page.UseSafeArea specyficzne dla iOS rozwiązaniem cross-platform.
<!-- Granular safe area control per section -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
SafeAreaEdges="All">
<Grid RowDefinitions="Auto,*,Auto">
<!-- Header respects all safe areas -->
<Border Grid.Row="0" SafeAreaEdges="Container">
<Label Text="Header" />
</Border>
<!-- Content scrolls under safe areas -->
<ScrollView Grid.Row="1" SafeAreaEdges="SoftInput">
<VerticalStackLayout Padding="16">
<Entry Placeholder="Type here..." />
</VerticalStackLayout>
</ScrollView>
<!-- Footer avoids home indicator -->
<Border Grid.Row="2" SafeAreaEdges="Container">
<Label Text="Footer" />
</Border>
</Grid>
</ContentPage>SoftInput dostosowuje zawartość, gdy pojawia się klawiatura ekranowa. Container unika wcięć, obudów sensorów i wskaźnika home. Wartości te można łączyć per kontrolka.
Migracja z Xamarin.Forms do .NET MAUI
Wsparcie dla Xamarin.Forms zakończyło się w maju 2024 roku. Migracja do MAUI wymaga zmian strukturalnych wykraczających poza prostą zamianę przestrzeni nazw.
Xamarin.Forms nie jest wspierany od maja 2024 roku. Aplikacje nadal działające na Xamarin niosą ze sobą ryzyko bezpieczeństwa i kompatybilności. .NET MAUI 10 (LTS, wsparcie do listopada 2028) jest wyznaczonym celem migracji.
- Struktura projektu — konwersja z projektów specyficznych dla platform do modelu pojedynczego projektu MAUI
- Przestrzenie nazw — zamiana
Xamarin.FormsnaMicrosoft.Maui.ControlsiXamarin.EssentialsnaMicrosoft.Maui.Essentials - Renderery na handlery — niestandardowe renderery muszą zostać przepisane jako handlery
- Inicjalizacja — zastąpienie inicjalizacji
App.xaml.cswzorcem builder wMauiProgram.cs - Pakiety NuGet — wiele pakietów z ery Xamarin ma odpowiedniki MAUI
- Wstrzykiwanie zależności — MAUI natywnie używa
Microsoft.Extensions.DependencyInjection
Najważniejsze pytania rekrutacyjne .NET MAUI na 2026 rok
Poniższe pytania odzwierciedlają to, o co pytają zespoły rekrutacyjne w 2026 roku.
Czym architektura handlerów MAUI różni się od rendererów Xamarin.Forms?
Renderery w Xamarin.Forms były ściśle powiązane zarówno z kontrolką cross-platform, jak i widokiem natywnym, tworząc dwukierunkową zależność. Handlery w MAUI to bezstanowe mappery: otrzymują powiadomienia o zmianach właściwości i stosują je do widoku natywnego poprzez słownik mapperów. Słowniki PropertyMapper i CommandMapper zastępują wzorzec nadpisywania OnElementPropertyChanged, czyniąc dostosowywanie jawnym.
Jakie są pułapki związane z czasem życia DI specyficzne dla MAUI?
MAUI obsługuje czasy życia Singleton, Transient i Scoped, ale Scoped zachowuje się inaczej niż w ASP.NET Core. Nie ma naturalnej granicy zakresu (jak żądanie HTTP). Typowe błędy: rejestrowanie ViewModelu jako Singleton, gdy przechowuje stan specyficzny dla strony (nieaktualne dane przy nawigacji), lub rejestrowanie połączenia z bazą danych jako Transient (wyczerpanie puli połączeń).
Odpowiadając na pytania o DI, należy wykazać zrozumienie, czym cykl życia MAUI różni się od modelu request-scoped ASP.NET Core. Rekruterzy szukają świadomości wycieków pamięci i problemów z przestarzałym stanem specyficznych dla długo działających aplikacji mobilnych.
Czym kompilowane bindowanie różni się od bindowania opartego na refleksji?
Bindowania oparte na refleksji rozwiązują ścieżki właściwości w runtime przy użyciu System.Reflection, co jest wolne i generuje błędy runtime przy literówkach. Kompilowane bindowania, włączane za pomocą x:DataType, rozwiązują ścieżki bindowań w czasie kompilacji. Kompilator generuje bezpośredni kod dostępu do właściwości, pomijając refleksję. Poprawia to czas uruchomienia, redukuje alokacje pamięci i wychwytuje błędy bindowań podczas budowania.
Jakie strategie istnieją do współdzielenia kodu między aplikacją MAUI a backendem ASP.NET Core?
Zalecane podejście wykorzystuje współdzieloną bibliotekę klas zawierającą DTO, logikę walidacji i reguły biznesowe. Zarówno aplikacja MAUI, jak i backend ASP.NET Core referencjonują tę bibliotekę. .NET 10 wzmacnia ten wzorzec integracją .NET Aspire dla MAUI, zapewniającą odkrywanie usług i telemetrię między projektami mobilnymi i backendowymi.
Czym HybridWebView różni się od BlazorWebView w MAUI?
BlazorWebView hostuje pełną aplikację Blazor wewnątrz aplikacji MAUI. Komponenty Razor renderują się w osadzonym WebView, ale runtime .NET wykonuje się natywnie (nie przez WebAssembly). HybridWebView jest lżejszy: ładuje statyczną zawartość HTML/CSS/JS i zapewnia interop C#-JavaScript bez narzutu frameworka Blazor. BlazorWebView pasuje do zespołów z istniejącymi komponentami Blazor, które chcą ponownego użycia kodu. HybridWebView pasuje do scenariuszy, w których istniejąca zawartość webowa wymaga natywnej integracji bez pełnego frameworka.
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Podsumowanie
- .NET MAUI 10 to wydanie LTS (wsparcie do listopada 2028) skoncentrowane na stabilności i wydajności — niezawodny wybór do produkcyjnych aplikacji cross-platform
- Architektura handlerów zastępuje renderery Xamarin bezstanowymi mapperami, poprawiając testowalność i dostosowywanie poprzez
PropertyMapperiCommandMapper - Generatory kodu źródłowego CommunityToolkit.Mvvm usuwają większość kodu boilerplate MVVM — atrybuty
[ObservableProperty]i[RelayCommand]zastępują ręczne implementacje - HybridWebView w .NET 10 dodaje wywołania JavaScript fire-and-forget, zdarzenia inicjalizacji i przechwytywanie żądań dla integracji natywno-webowej
- SafeAreaEdges zapewnia granularną, cross-platformową kontrolę nad wycięciami urządzeń, klawiaturami i paskami systemowymi
- Migracja z Xamarin.Forms wymaga przepisania handlerów i refaktoryzacji inicjalizacji
- Przygotowanie do rozmów kwalifikacyjnych powinno koncentrować się na architekturze handler vs. renderer, pułapkach DI, kompilowanych bindowaniach oraz kompromisach HybridWebView vs. BlazorWebView
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Tagi
Udostępnij
Powiązane artykuły

.NET 9 Blazor: Pełnostackowy rozwój aplikacji z Blazor United w 2026
.NET 9 Blazor United łączy statyczny SSR, Server i WebAssembly w jednym frameworku full-stack. Praktyczny poradnik obejmujący tryby renderowania, streaming rendering, wstrzykiwanie zależności i wzorce produkcyjne.

Entity Framework Core: Optymalizacja wydajności i najlepsze praktyki w 2026
Kompleksowy przewodnik po optymalizacji EF Core 10. Poznaj techniki zwiększania wydajności zapytań, zarządzania pamięcią i skalowania aplikacji .NET.

Clean Architecture w .NET: Praktyczny Przewodnik
Opanowanie Clean Architecture w .NET z C#. Poznanie zasad SOLID, separacji warstw i wzorców implementacyjnych dla aplikacji łatwych w utrzymaniu.