.NET Multi-platform App UI (.NET MAUI)

repository·main·Indexed 12 days ago

https://github.com/dotnet/maui

A cross-platform framework for building native mobile and desktop applications for Android, iOS, macOS, and Windows from a single C# and XAML codebase. It features a unified SDK and toolchain, supporting the MVVM pattern, Shell navigation, and specialized controls like Microsoft.Maui.Controls.Maps.

Tokens
35.2K
Snippets
101
Records
154
Agent score
98%

What's inside .NET MAUI

  1. Overview of .NET MAUI NuGet and Workload Artifacts

    main

    The .NET MAUI ecosystem is composed of several distinct types of packages. Understanding these helps in identifying which package provides specific functionality:

    Workload Packages

    Used by the .NET SDK to install the MAUI environment:

    • Microsoft.NET.Sdk.Maui.Manifest: The workload manifest.
    • Microsoft.Maui.Sdk: The actual .NET MAUI workload SDK.
    • Microsoft.Maui.Templates.net*: Project templates for the current build.

    .NET MAUI Framework Packages

    Core libraries for building applications:

    • Microsoft.Maui.Controls: The root package for UI controls. It includes Microsoft.Maui.Controls.Core (assemblies), Microsoft.Maui.Controls.Xaml (XAML parser), and Microsoft.Maui.Controls.Build.Tasks (XAML[C|G] targets).
    • Microsoft.Maui.Core: Base interfaces and handlers.
    • Microsoft.Maui.Essentials: Cross-platform APIs.
    • Microsoft.Maui.Resizetizer: Asset generator and integrator.
    • Microsoft.Maui.Controls.Compatibility: APIs for Xamarin.Forms compatibility.

    Specialized Support Packages

    • Maps: Microsoft.Maui.Controls.Maps (XAML controls) and Microsoft.Maui.Maps (handlers/interfaces).
    • Foldable/Dual-Screen: Microsoft.Maui.Controls.Foldable.
    • Graphics: Microsoft.Maui.Graphics (core engine), Microsoft.Maui.Graphics.Skia (SkiaSharp-based), and Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.
    • Blazor Desktop/Mobile: Microsoft.AspNetCore.Components.WebView.Maui (and platform-specific versions for Windows Forms/WPF).
  2. Overview of .NET MAUI

    main

    .NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating mobile and desktop applications using C# and XAML. It is the evolution of Xamarin.Forms.

    Key Capabilities:

    • Single Codebase: Develop once and run on Android, iOS, iPadOS, macOS, and Windows.
    • Unified Stack: Uses a single SDK, base class libraries, and toolchain.
    • Target Platforms: Android, iOS, iPadOS, macOS, and Windows.
  3. Understand the .NET MAUI Release Process

    main

    The .NET MAUI release process is split into two distinct phases managed via the Arcade SDK infrastructure. This process ensures that packages are built, signed, and published to both NuGet.org and the .NET SDK Workload Set channels.

    Phase 1: Build and Pack

    Handled by the azure-pipelines-internal.yml pipeline. This phase is automated and runs on a schedule or upon commits to main/release branches. It performs:

    • Source Provisioning: Setting up dependencies (e.g., Android SDKs).
    • Build & Pack: Compiling projects and creating NuGet packages.
    • Signing: Applying Microsoft certificates to official builds.
    • Workload Construction: Building workload manifests and packages.
    • BAR Registration: Publishing package metadata to the Build Asset Registry (BAR) in Maestro using darc.

    Phase 2: Publishing (Release)

    Handled by the maui-release-internal.yml pipeline. This phase is manual and requires specific parameters to target different channels.

    • Workload Set Channel: Publishes the workload set to a specific .NET SDK channel (e.g., .NET 8, 9, or 10 Workload Release).
    • Release Packs: Pushes NuGet packages to NuGet.org (requires manual approval).
    • Release Manifests: Pushes manifest packages to NuGet.org (requires separate manual approval).
  4. Responding to 'PR: pending author input' labels

    main

    When a Pull Request (PR) requires follow-up changes or information from the author, it will be marked with the s/pr-needs-author-input label.

    • Response Window: You are expected to respond or update the PR within 14 days.
    • Automatic Closure: If no response or update is provided within 14 days, the PR will be automatically closed.
    • Re-opening: If you respond within 7 days after the PR has been closed, the PR will be automatically re-opened.
  5. Use XAML C# Expressions for direct code execution

    main

    XAML C# Expressions allow you to write C# expressions directly within XAML attribute values. A source generator parses these expressions to create bindings, call methods, or generate event handlers, reducing the need for boilerplate code-behind or complex bindings for simple computations.

    Supported Expression Types

    • Simple Expressions: Single identifiers or property paths (e.g., {Username}).
    • Lambda for Events: Inline event handlers (e.g., {(s, e) => Count++}).
    • Compound Expressions: Combining multiple sources using operators (e.g., {Price * GetTaxRate()}).
    • String Interpolation: Using the $ prefix (e.g., {$'{FirstName} {LastName}'}).

    Limitations

    • SourceGen only: These expressions are not available in XamlC or via runtime inflation.
    • No Async Lambdas: You cannot use {async (s, e) => ...}. Use a regular method instead.
    • Single Expressions: You cannot use multi-statement blocks or control flow (if/else).
    • Event Parameters: Lambdas must include parameters, e.g., {(s, e) => ...}.
    <StackLayout>
      <Label Text="{$'{FirstName} {LastName}'}" />
      <Label Text="{Items.Count}" />
      <Button Clicked="{(s, e) => Count++}" />
    </StackLayout>
  6. Understand MauiFactory and IMauiHandlersFactory

    main

    MauiFactory

    MauiFactory is a specialized dependency resolver used by .NET MAUI. While the project primarily uses Microsoft.Extensions.DependencyInjection (MS.Ext.DI), MauiFactory is retained for specific needs:

    • Decoupled Registration: It allows registering two types that have no inheritance or interface relationship (e.g., mapping a Button to a ButtonHandler even if they share no common hierarchy).
    • Dynamic Registration: Through IMauiHandlersFactory, handlers can theoretically be added to the IMauiHandlersCollection at runtime.

    IMauiHandlersFactory

    IMauiHandlersFactory is the interface used to request handlers for a View. It inherits from IMauiFactory (which implements IServiceProvider).

  7. Use MVVM and Data Binding in .NET MAUI

    main

    Implement the Model-View-ViewModel (MVVM) pattern using XAML data binding. You can bind properties like Text to ViewModel properties, and use Mode=TwoWay for input controls like Entry to ensure changes flow back to the source.

    <Label Text="{Binding UserName}" />
    <Entry Text="{Binding Email, Mode=TwoWay}" />
  8. Customize Package Mappings and Version Handling

    main

    The cgmanifest.json generation is driven by the PowerShell script located at eng/scripts/update-cgmanifest.ps1.

    Modifying Mappings

    To add or modify how packages are mapped, edit the $packageVersionMappings hashtable within the script.

    Handling Multiple Versions

    The script supports including multiple versions of a single package (e.g., both current and previous versions). For example, CommunityToolkit.Maui uses both CommunityToolkitMauiPackageVersion and CommunityToolkitMauiPreviousPackageVersion from Versions.props. To implement this for a new package, you must add custom logic to the PowerShell script similar to the existing CommunityToolkit.Maui implementation.

    Manual Entries

    You can manually add packages to cgmanifest.json. The update scripts are designed to preserve manually added entries and will only update versions for packages they explicitly recognize.

  9. How MAUI Controls and Core targets are structured

    main

    MAUI distributes build logic across different NuGet packages using specific directory structures to handle cross-platform requirements.

    Controls (Microsoft.Maui.Controls.Build.Tasks)

    This package manages XAML compilation and build tasks. It uses a three-tier structure:

    1. Platform Folders: If a platform folder exists in the NuGet, it acts as a redirection to import netstandard targets. The .props files here provide platform-specific customization.
    2. .NET Standard Files: Located in a netstandard folder. This is where the actual work happens (setting globs, XAML compiler tasks, analyzers, and AOT profiles). This folder is used because the build tasks assembly must be compatible with both full MSBuild and dotnet core MSBuild.
    3. Root Files: Acts as a fallback for platforms that do not recognize netstandard as a valid TFM (e.g., Windows).

    Core (Microsoft.Maui.Core)

    Targets and props for Core are located in the root of buildTransitive so all platforms can access them without duplication.

    • Windows Exception: Because Windows requires platform-specific properties, it has its own TFM folder. The Windows targets/props in that folder import the root files after applying Windows-specific overrides and Windows App SDK workarounds.
  10. Understand Arcade template types: shim, logic, and redirect

    main

    Arcade's template architecture uses three distinct types of YAML files to manage the difference between standard and 1ES pipelines:

    • shim: An intermediate YAML file that acts as an entry point. It defines the is1ESPipeline parameter (set to true if in templates-official, false if in templates) and redirects to the actual logic. Shims are typically used at the stages, jobs, and job levels.
    • logic: The actual base template logic. Most logic resides in the core-templates folder.
    • redirect: A file in core-templates that redirects back to specific logic files in either templates or templates-official when the logic is dependent on the shim entry point used.

    Key Behavior:

    • Templates at the steps and variables levels are usually too granular for shims and contain direct logic applicable to both scenarios.
  11. Two-way binding support in expressions

    main

    Not all XAML C# expressions support two-way binding. The generator can only create a setter for simple property paths.

    • Supported (Two-Way): Simple property paths like {Name} or {User.Name}.
    • Not Supported (One-Way Only): Any expression involving operators, method calls, or logic, such as {Price * Qty} or {Name.ToUpper()}.

    If you attempt to use a complex expression on a property that requires two-way binding, you will receive diagnostic MAUIX2010.

  12. How Window Scoping works in .NET MAUI

    main

    In .NET MAUI, services can be scoped to a specific Window (such as an AppCompatActivity on Android, UIScene on iOS, or UI.XAML.Window on Windows). When a new Window is created, .NET MAUI uses the CreateScope method from Microsoft.Extensions.DependencyInjection to generate a new scope from the application-level IServiceProvider.

    This mechanism allows you to register services that should only exist for the lifetime of a specific window, such as:

    • IDispatcher
    • ITicket
    • IAnimationManager