Neuigkeiten in .NET MAUI für .NET 9

Der Schwerpunkt der .NET Multi-Platform App-Benutzeroberfläche (.NET MAUI) in .NET 9 ist die Verbesserung der Produktqualität. Dazu gehören die Erweiterung der Prüfungsabdeckung, das Testen von End-to-End-Szenarien und die Fehlerbehebung. Weitere Informationen zu den Verbesserungen der Produktqualität in .NET MAUI 9 finden Sie in den folgenden Versionshinweisen:

Wichtig

Aufgrund der Arbeit mit externen Abhängigkeiten, wie z.B. Xcode oder Android SDK Tools, unterscheidet sich die Supportrichtlinie für .NET MAUI von der Supportrichtlinie für .NET und .NET Core. Weitere Informationen finden Sie in der Supportrichtlinie für .NET MAUI.

In .NET 9 wird .NET MAUI als .NET-Workload und mehrere NuGet-Pakete ausgeliefert. Der Vorteil dieses Ansatzes besteht darin, dass Sie Ihre Projekte einfach an bestimmte Versionen anheften können, während Sie gleichzeitig eine Vorschau auf unveröffentlichte oder experimentelle Builds erhalten. Wenn Sie ein neues .NET MAUI-Projekt erstellen, werden die erforderlichen NuGet-Pakete automatisch zum Projekt hinzugefügt.

Neue Steuerelemente

.NET MAUI 9 enthält zwei neue Steuerelemente.

HybridWebView

HybridWebView ermöglicht das Hosten beliebiger HTML/JS/CSS-Inhalte in einer Webansicht und ermöglicht die Kommunikation zwischen dem Code in der Webansicht (JavaScript) und dem Code, der die Webansicht hostet (C#/.NET). Wenn Sie beispielsweise eine React-JS-App haben, können Sie diese in einer plattformübergreifenden nativen .NET-MAUI-App hosten und das Back-End der App mit C# und .NET erstellen.

Um eine .NET MAUI App mit HybridWebView zu erstellen, benötigen Sie:

  • Den Webinhalt der App, der aus statischem HTML, JavaScript, CSS, Bildern und anderen Dateien besteht.
  • Ein HybridWebView-Steuerelement als Teil der Benutzeroberfläche der App. Dies kann erreicht werden, indem es im XAML-Code der App referenziert wird.
  • Code im Webinhalt und in C#/.NET, der die HybridWebView-APIs verwendet, um Nachrichten zwischen den beiden Komponenten zu senden.

Die gesamte App, einschließlich der Webinhalte, ist verpackt und läuft lokal auf einem Gerät und kann in den entsprechenden App-Stores veröffentlicht werden. Der Webinhalt wird in einer nativen Webansicht gehostet und läuft im Kontext der App. Jeder Teil der App kann auf externe Webdienste zugreifen, muss dies aber nicht.

Weitere Informationen finden Sie unter HybridWebView.

Titelleiste für Windows

Das TitleBar-Steuerelement bietet die Möglichkeit, Ihrer App unter Windows eine benutzerdefinierte Titelleiste hinzuzufügen:

Übersicht über die .NET MAUI-Titelleiste.

Eine TitleBar kann als Wert der Window.TitleBar-Eigenschaft auf jedem Window festgelegt werden:

<Window.TitleBar>
    <TitleBar x:Name="TeamsTitleBar"
              Title="Hello World"
              Icon="appicon.png"
              HeightRequest="46">
        <TitleBar.Content>
            <Entry x:Name="SearchTitleBar"
                   Placeholder="Search"
                   VerticalOptions="Center"
                   MinimumWidthRequest="300"
                   MaximumWidthRequest="450"
                   HeightRequest="32"/>
        </TitleBar.Content>
    </TitleBar>
</Window.TitleBar>

Ein Beispiel für die Verwendung in C# ist:

Window.TitleBar = new TitleBar
{
    Title = "MAUI App",
    Icon = "appicon.png",
    HeightRequest = 46,
    LeadingContent = new AvatarButton()
};

Eine TitleBar ist durch ihre Eigenschaften Content, LeadingContent und TrailingContent in hohem Maße anpassbar:

<TitleBar Title="My App"
          BackgroundColor="#512BD4"
          HeightRequest="48">
    <TitleBar.Content>
        <SearchBar Placeholder="Search"
                   MaximumWidthRequest="300"
                   HorizontalOptions="FillAndExpand"
                   VerticalOptions="Center" />
    </TitleBar.Content>
    <TitleBar.TrailingContent>
        <ImageButton HeightRequest="36"
                     WidthRequest="36"
                     BorderWidth="0"
                     Background="Transparent">
            <ImageButton.Source>
                <FontImageSource Size="16"
                                 Glyph="&#xE713;"
                                 FontFamily="SegoeMDL2"/>
            </ImageButton.Source>
        </ImageButton>
    </TitleBar.TrailingContent>
</TitleBar>

Der folgende Screenshot zeigt das Ergebnis :

Screenshot der .NET MAUI-Titelleiste.

Hinweis

Mac Catalyst-Unterstützung für das TitleBar-Steuerelement wird in einer zukünftigen Version hinzugefügt.

Steuerelementverbesserungen

.NET MAUI 9 enthält auch Steuerelementverbesserungen.

BackButtonBehavior OneWay-Verknüpfungsmodus

Der Bindungsmodus für IsVisible und IsEnabled auf einem BackButtonBehavior in einer Shell-App ist jetzt BindingMode.OneWay statt BindingMode.OneTime. Auf diese Weise können Sie das Verhalten der Zurück-Schaltfläche zur Laufzeit mit Datenbindungen einfacher steuern:

<ContentPage ...>    
    <Shell.BackButtonBehavior>
        <BackButtonBehavior Command="{Binding BackCommand}"
                            IsVisible="{Binding IsBackButtonVisible}"
                            IconOverride="back.png" />   
    </Shell.BackButtonBehavior>
    ...
</ContentPage>

BlazorWebView

Unter iOS und Mac Catalyst 18 ändert .NET MAUI 9 das Standardverhalten für das Hosting von Inhalten in einem BlazorWebView auf localhost. Die interne 0.0.0.0-Adresse, die zum Hosten von Inhalten verwendet wurde, funktioniert nicht mehr und führt dazu, das BlazorWebView keine Inhalte lädt und ein leeres Rechteck angezeigt wird.

Um sich für die Verwendung der 0.0.0.0 Adresse zu entscheiden, fügen Sie Ihrer MauiProgram-Klasse den folgenden Code hinzu:

// Set this switch to use the LEGACY behavior of always using 0.0.0.0 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);

CollectionView und KarussellView

.NET MAUI 9 enthält zwei optionale neue Handler unter iOS und Mac Catalyst, die die Leistung und Stabilität von CollectionView und CarouselView verbessern. Diese Handler basieren auf UICollectionView-APIs.

Um diese Handler zu verwenden, fügen Sie Ihrer MauiProgram-Klasse den folgenden Code hinzu:

#if IOS || MACCATALYST
builder.ConfigureMauiHandlers(handlers =>
{
    handlers.AddHandler<Microsoft.Maui.Controls.CollectionView, Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2>();
    handlers.AddHandler<Microsoft.Maui.Controls.CarouselView, Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2>();
});
#endif

Beschriftungstextausrichtung

Sie können jetzt Text in Label-Objekten mit HorizontalTextAlignment.Justify horizontal ausrichten:

<Label Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis nulla eu felis fringilla vulputate."
       HorizontalTextAlignment="Justify"/>

Unterstützung für die Bildschirmtastatureingabe

.NET MAUI 9 unterstützt jetzt die Bildschirmtastatureingabe für Password, Date und Time. Diese können für Editor- und Entry-Steuerelemente aktiviert werden:

<Entry Keyboard="Date" />

TimePicker

TimePicker erhält ein TimeSelected Ereignis, das ausgelöst wird, wenn sich die ausgewählte Zeit ändert. Das TimeChangedEventArgs-Objekt, das das TimeSelected-Ereignis begleitet, verfügt über die Eigenschaften NewTime bzw. OldTime, die die neue bzw. alte Zeit angeben.

WebView

WebView fügt ein ProcessTerminated-Ereignis hinzu, das ausgelöst wird, wenn ein WebView-Prozess unerwartet beendet wird. Das WebViewProcessTerminatedEventArgs-Objekt, das dieses Ereignis begleitet, definiert plattformspezifische Eigenschaften, die angeben, warum der Prozess fehlgeschlagen ist.

App-Lebenszyklus

.NET MAUI 9 fügt die folgenden Methoden für den Lebenszyklus der Fernbenachrichtigung auf iOS und Mac Catalyst hinzu:

  • RegisteredForRemoteNotifications, die aufgerufen wird, wenn sich die App erfolgreich für Remote-Benachrichtigungen registriert hat.
  • ReceivedRemoteNotifications, die aufgerufen wird, wenn eine Fernbenachrichtigung eingeht.

Das folgende Beispiel zeigt, wie diese Lebenszyklusmethoden verwendet werden:

using Microsoft.Maui.LifecycleEvents;

namespace PlatformLifecycleDemo;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureLifecycleEvents(events =>
            {
#if IOS || MACCATALYST
                events.AddiOS(ios => ios
                    .ReceivedRemoteNotifications((app, dictionary) => LogEvent(nameof(iOSLifecycle.OnReceivedRemoteNotifications)))
                    .RegisteredForRemoteNotifications((app, data) => LogEvent(nameof(iOSLifecycle.OnRegisteredForRemoteNotifications)));
#endif
                static bool LogEvent(string eventName, string type = null)
                {
                    System.Diagnostics.Debug.WriteLine($"Lifecycle event: {eventName}{(type == null ? string.Empty : $" ({type})")}");
                    return true;
                }
            });

        return builder.Build();
    }
}

Trennen des Handlers

Bei der Implementierung einer benutzerdefinierten Steuerung mithilfe von Handlern muss jede Plattform-Handler-Implementierung die DisconnectHandler-Methode implementieren, um eine native Bereinigung der Ansicht durchzuführen, z. B. das Abbestellen von Ereignissen. Vor .NET MAUI 9 wird die DisconnectHandler-Implementierung jedoch absichtlich nicht von .NET MAUI aufgerufen. Stattdessen müssen Sie es selbst aufrufen, wenn Sie sich entscheiden, ein Steuerelement zu bereinigen, z. B. wenn Sie in einer App rückwärts navigieren.

In .NET MAUI 9 trennen Handler nach Möglichkeit automatisch die Verbindung mit ihren Steuerelementen, z. B. beim Rückwärts navigieren in einer App. In einigen Szenarien möchten Sie dieses Verhalten möglicherweise nicht. Daher fügt .NET MAUI 9 die angehängte Eigenschaft HandlerProperties.DisconnectPolicy hinzu, mit der gesteuert werden kann, wann Handler von ihren Steuerelementen getrennt werden. Diese Eigenschaft erfordert ein HandlerDisconnectPolicy-Argument, wobei die HandlerDisconnectPolicy-Enumeration die folgenden Werte definiert:

  • Automatic, der angibt, dass Handler automatisch getrennt werden. Dies ist der Standardwert der angefügten HandlerProperties.DisconnectPolicy-Eigenschaft.
  • Manual, der angibt, dass Handler manuell getrennt werden müssen, indem sie die DisconnectHandler-Implementierung aufrufen.

Das folgende Beispiel zeigt, wie die angehängte Eigenschaft HandlerProperties.DisconnectPolicy festgelegt wird:

<controls:Video x:Name="video"
                HandlerProperties.DisconnectPolicy="Manual"
                Source="video.mp4"
                AutoPlay="False" />

Der entsprechende C#-Code lautet:

Video video = new Video
{
    Source = "video.mp4",
    AutoPlay = false
};
HandlerProperties.SetDisconnectPolicy(video, HandlerDisconnectPolicy.Manual);

Zusätzlich gibt es eine DisconnectHandlers-Erweiterungsmethode, die Handler von einer bestimmten IView trennt:

video.DisconnectHandlers();

Beim Trennen der Verbindung wird die DisconnectHandlers-Methode in der Struktur des Steuerelements nach unten weitergegeben, bis sie abgeschlossen ist oder eine Steuerung erreicht, die eine manuelle Richtlinie festgelegt hat.

Unterstützung für mehrere Fenster

.NET MAUI 9 bietet die Möglichkeit, ein bestimmtes Fenster auf Mac Catalyst und Windows mit der Application.Current.ActivateWindow-Methode in den Vordergrund zu bringen:

Application.Current?.ActivateWindow(windowToActivate);

Native Einbettung

.NET MAUI 9 enthält vollständige APIs für native Einbettungsszenarien, die zuvor manuell zu Ihrem Projekt hinzugefügt werden mussten:

var mauiApp = MauiProgram.CreateMauiApp();

#if ANDROID
var mauiContext = new MauiContext(mauiApp.Services, window);
#else
var mauiContext = new MauiContext(mauiApp.Services);
#endif

var mauiView = new MyMauiContent();
var nativeView = mauiView.ToPlatform(mauiContext);

Alternativ können Sie die ToPlatformEmbedded-Methode verwenden und Window für die Plattform angeben, auf der die App ausgeführt wird:

var mauiApp = MauiProgram.CreateMauiApp();
var mauiView = new MyMauiContent();
var nativeView = mauiView.ToPlatformEmbedded(mauiApp, window);

In beiden Beispielen ist nativeView eine plattformspezifische Version von mauiView.

Um eine native eingebettete App in .NET MAUI 9 zu bootstrappen, rufen Sie die UseMauiEmbeddedApp-Erweiterungsmethode für Ihr MauiAppBuilder-Objekt auf:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

        builder
            .UseMauiEmbeddedApp<App>();

        return builder.Build();
    }
}

Projektvorlagen

.NET MAUI 9 fügt Visual Studio eine .NET MAUI Blazor Hybrid- und Web-App-Projektvorlage hinzu, die eine Lösung mit einer .NET MAUI Blazor Hybrid-App und einer Blazor-Web-App erstellt, die den gängigen Code in einem Razor-Klassenbibliothek-Projekt gemeinsam nutzen.

Die Vorlage kann auch über dotnew new verwendet werden:

dotnet new maui-blazor-web -n AllTheTargets

Xcode-Synchronisierung

.NET MAUI 9 enthält Xcode-Synchronisierung (xcsync), ein Tool, mit dem Sie Xcode zum Verwalten von Apple-spezifischen Dateien mit .NET-Projekten verwenden können, einschließlich Objektkataloge, Plist-Dateien, Storyboards und XIB-Dateien. Das Tool verfügt über zwei Hauptbefehle, um ein temporäres Xcode-Projekt aus einem .NET-Projekt zu generieren und Änderungen aus den Xcode-Dateien wieder mit Ihrem .NET-Projekt zu synchronisieren.

Sie verwenden dotnet build mit den Befehlen xcsync-generate oder xcsync-sync, um diese Dateien zu generieren oder zu synchronisieren, und übergeben eine Projektdatei und zusätzliche Argumente:

dotnet build /t:xcsync-generate
    /p:xcSyncProjectFile=<PROJECT>
    /p:xcSyncXcodeFolder=<TARGET_XCODE_DIRECTORY>
    /p:xcSyncTargetFrameworkMoniker=<FRAMEWORK>
    /p:xcSyncVerbosity=<LEVEL>

Weitere Informationen finden Sie unter Xcode-Synchronisierung.

Nicht mehr unterstützte APIs

.NET MAUI 9 stellt einige APIs ein, die in einer zukünftigen Version vollständig entfernt werden.

Frame

Das Steuerelement Frame ist in .NET MAUI 9 als eingestellt gekennzeichnet und wird in einer zukünftigen Version vollständig entfernt. An seiner Stelle sollte das Border-Steuerelement verwendet werden. Weitere Informationen finden Sie unter Border.

MainPage

Anstatt die erste Seite Ihrer App mithilfe der MainPage-Eigenschaft für ein Application-Objekt zu definieren, sollten Sie die Page-Eigenschaft für ein Window auf die erste Seite Ihrer App festlegen. Dies geschieht intern in .NET MAUI, wenn Sie die MainPage-Eigenschaft festlegen, sodass sich das Verhalten nicht ändert, wenn die MainPage-Eigenschaft als eingestellt markiert wird.

Das folgende Beispiel zeigt, wie die Eigenschaft Page für Window über die CreateWindow-Überschreibung festgelegt wird:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }

    protected override Window CreateWindow(IActivationState? activationState)
    {
        return new Window(new AppShell());
    }
}

Die Eigenschaft MainPage wird für .NET MAUI 9 beibehalten, wird aber in einer zukünftigen Version vollständig entfernt.

Kompatibilitätslayouts

Die Kompatibilitätslayoutklassen im Namespace Microsoft.Maui.Controls.Compatibility wurden eingestellt.

Legacy-Measureaufrufe

Die folgenden VisualElement-Legacy-Measuremethoden wurden eingestellt:

  • protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint).
  • public virtual SizeRequest Measure(double widthConstraint, double heightConstraint, MeasureFlags flags = MeasureFlags.None) von VisualElement.

Als Ersatz wurde die folgende Methode eingeführt:

  • public size Measure(double widthConstraint, double heightConstraint)

Diese Measure-Methode gibt die Mindestgröße zurück, die ein Element benötigt, um auf einem Gerät angezeigt zu werden. Ränder sind von der Messung ausgeschlossen, werden aber mit der Größe zurückgegeben. Dies ist die bevorzugte Methode, die beim Messen einer Ansicht aufgerufen werden soll.

Darüber hinaus ist die Microsoft.Maui.SizeRequest-Struktur veraltet. Stattdessen sollte Microsoft.Maui.Size verwendet werden.

.NET für Android

.NET für Android 9, das Unterstützung für API 35 hinzufügt, umfasst Arbeiten zur Verkürzung der Erstellungszeiten und zur Verbesserung der Anpassungsfähigkeit von Apps, um die Größe zu reduzieren und die Leistung zu verbessern. Weitere Informationen zu .NET für Android 9 finden Sie in den folgenden Versionshinweisen:

Ressourcenpakete

.NET für Android 9 bietet die Möglichkeit, Assets in einem separaten Paket, einem sogenannten Ressourcenpaket, zu platzieren. Auf diese Weise können Sie Spiele und Apps hochladen, die normalerweise größer als die von Google Play zulässige Standardpaketgröße sind. Indem Sie diese Ressourcen in ein separates Paket einfügen, erhalten Sie die Möglichkeit, ein Paket hochzuladen, das bis zu 2 GB groß ist, und nicht die normale Paketgröße von 200 MB hat.

Wichtig

Ressourcenpakete können nur Ressourcen enthalten. Im Fall von .NET for Android bedeutet dies Elemente, die über die AndroidAsset-Buildaktion verfügen.

.NET MAUI-Apps definieren Ressourcen über die MauiAsset-Buildaktion. Ein Ressourcenpaket kann über das AssetPack-Attribut angegeben werden:

<MauiAsset
    Include="Resources\Raw\**"
    LogicalName="%(RecursiveDir)%(Filename)%(Extension)"
    AssetPack="myassetpack" />

Hinweis

Die zusätzlichen Metadaten werden von anderen Plattformen ignoriert.

Wenn Sie bestimmte Elemente haben, die Sie in einem Ressourcenpaket platzieren möchten, können Sie das Update-Attribut verwenden, um die AssetPack-Metadaten zu definieren:

<MauiAsset Update="Resources\Raw\MyLargeAsset.txt" AssetPack="myassetpack" />

Ressourcenpakete können unterschiedliche Übermittlungsoptionen haben, die steuern, wann Ihre Objekte auf dem Gerät installiert werden:

  • Installationszeitpakete werden gleichzeitig mit der App installiert. Dieser Packettyp kann bis zu 1 GB groß sein, aber Sie können nur eins davon haben. Dieser Übermittlungstyp wird mit InstallTime-Metadaten angegeben.
  • Fast Follow Packs werden zu einem bestimmten Zeitpunkt installiert, nachdem die App die Installation abgeschlossen hat. Die App kann während der Installation dieses Pakettyps gestartet werden, also sollten Sie überprüfen, ob die Installation abgeschlossen ist, bevor Sie versuchen, diese Ressourcen zu verwenden. Diese Art von Ressourcenpaket kann bis zu 512 MB groß sein. Dieser Übermittlungstyp wird mit FastFollow-Metadaten angegeben.
  • On Demand Packs werden nie auf das Gerät heruntergeladen, es sei denn, die App fordert sie ausdrücklich an. Die Gesamtgröße aller Ressourcenpakete darf 2 GB nicht überschreiten und Sie können bis zu 50 separate Ressourcenpakete haben. Dieser Übermittlungstyp wird mit OnDemand-Metadaten angegeben.

In .NET MAUI-Apps kann der Übermittlungstyp mit dem DeliveryType-Attribut für ein MauiAsset festgelegt werden:

<MauiAsset Update="Resources\Raw\myvideo.mp4" AssetPack="myassetpack" DeliveryType="FastFollow" />

Weitere Informationen zu Android-Ressourcenpaketen finden Sie unter Android-Ressourcenpakete.

Android 15-Unterstützung

.NET für Android 9 fügt .NET-Verknüpfungen für Android 15 (API 35) hinzu. Um für diese APIs zu entwickeln, ändern Sie das Zielframework Ihres Projekts:

<TargetFramework>net9.0-android35</TargetFramework>

LLVM-Marshallmethoden

LLVM-Methoden (Low-Level Virtual Machine) sind jetzt standardmäßig in .NET für Android 9 in Nicht-Blazor-Apps aktiviert. Dies hat zu einer Leistungsverbesserung von ca. 10 Prozent in einer Test-App geführt.

LLVM-Marshallmethoden können in Ihrer Projektdatei deaktiviert werden (.csproj):

<PropertyGroup Condition="'$(TargetFramework)' == 'net9.0-android'">
    <AndroidEnableLLVM>false</AndroidEnableLLVM>
    <AndroidEnableLLVMOptimizations>false</AndroidEnableLLVMOptimizations>
</PropertyGroup>

Verbesserungen der Kürzungsfunktion

.NET für Android 9 enthält Korrekturen für die Verwendung des vollständigen Kürzens zur Reduzierung der Größe der App. Die vollständige Kürzung ist in der Regel nur für Releasebuilds Ihrer App aktiviert und kann in Ihrer Projektdatei konfiguriert werden (.csproj):

<PropertyGroup Condition="'$(Configuration)' == 'Release' And '$(TargetFramework)' == 'net9.0-android'">
    <TrimMode>Full</TrimMode>
</PropertyGroup>

.NET für iOS

.NET 9 unter iOS, tvOS, Mac Catalyst und macOS verwendet Xcode 15.4 für die folgenden Plattformversionen:

  • iOS: 17.5
  • tvOS: 17.5
  • Mac Catalyst: 17.5
  • macOS: 14.5

Weitere Informationen zu .NET 9 unter iOS, tvOS, Mac Catalyst und macOS finden Sie in den folgenden Versionshinweisen:

Bindungen

.NET für iOS 9 führt die Möglichkeit ein, Versionen von .NET für iOS-Verknüpfungen mehrfach zu nutzen. Ein Bibliotheksprojekt muss z. B. für zwei unterschiedliche iOS-Versionen erstellt werden:

<TargetFrameworks>net9.0-ios17.0;net9.0-ios17.2</TargetFrameworks>

Dies erzeugt zwei Bibliotheken, eine mit iOS 17.0-Bindungen und eine mit iOS 17.2-Bindungen.

Wichtig

Ein App-Projekt sollte immer auf das neueste iOS SDK abzielen.

Nativer AOT für iOS und Mac Catalyst

In .NET für iOS 9 nutzt die native AOT-Kompilierung (Ahead of Time) für iOS und Mac Catalyst die Vorteile der vollständigen Kürzung, um die Paketgröße zu reduzieren und die Startleistung Ihrer App zu verbessern. Dies ist ein Feature, das Sie verwenden können, wenn Sie bereit sind, Ihre App zu veröffentlichen.

Wichtig

Ihre App und deren Abhängigkeiten müssen vollständig kürzbar sein, um dieses Feature nutzen zu können.

Weitere Informationen