Condividi tramite


Novità di .NET MAUI per .NET 9

L'obiettivo dell'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) in .NET 9 è migliorare la qualità del prodotto. Sono inclusi l'espansione della copertura dei test, i test degli scenari end-to-end e la correzione di bug. Per altre informazioni sui miglioramenti della qualità del prodotto in .NET MAUI 9, vedere le note sulla versione seguenti:

Importante

A causa dell'uso di dipendenze esterne, ad esempio Xcode o Android SDK Tools, i criteri di supporto di .NET MAUI differiscono dai criteri di supporto di .NET e .NET Core. Per altre informazioni, vedere Criteri di supporto di .NET MAUI.

La compatibilità con Xcode 16, che include il supporto SDK per iOS 18, iPadOS 18, tvOS 18 e macOS 15, è necessario per la compilazione con .NET MAUI 9. Xcode 16 richiede un Mac che esegue macOS 14.5 o versione successiva.

In .NET 9, .NET MAUI viene fornito come carico di lavoro .NET e più pacchetti NuGet. Il vantaggio di questo approccio è che consente di aggiungere facilmente i progetti a versioni specifiche, consentendo allo stesso tempo di visualizzare facilmente l'anteprima di build non definitive o sperimentali. Quando si crea un nuovo progetto MAUI .NET, i pacchetti NuGet necessari vengono aggiunti automaticamente al progetto.

Destinazioni di distribuzione minime

.NET MAUI 9 richiede destinazioni di distribuzione minime di iOS 12.2 e Mac Catalyst 15.0 (macOS 12.0). Le destinazioni di distribuzione minima di Android e Windows rimangono invariate. Per altre informazioni, vedere Piattaforme supportate per le app MAUI .NET.

Nuovi controlli

.NET MAUI 9 include due nuovi controlli.

HybridWebView

HybridWebView abilita l'hosting di contenuto HTML/JS/CSS arbitrario in una visualizzazione Web e consente la comunicazione tra il codice nella visualizzazione Web (JavaScript) e il codice che ospita la visualizzazione Web (C#/.NET). Ad esempio, se si dispone di un'app React JS esistente, è possibile ospitarla in un'app nativa .NET MAUI multipiattaforma e compilare il back-end dell'app usando C# e .NET.

Per compilare un'app .NET MAUI con HybridWebView è necessario:

  • Contenuto Web dell'app, costituito da HTML statico, JavaScript, CSS, immagini e altri file.
  • Controllo HybridWebView come parte dell'interfaccia utente dell'app. A questo scopo, è possibile fare riferimento a esso nel codice XAML dell'app.
  • Codice nel contenuto Web e in C#/.NET che usa le HybridWebView API per inviare messaggi tra i due componenti.

L'intera app, incluso il contenuto Web, viene inserita in un pacchetto ed eseguita in locale in un dispositivo e può essere pubblicata negli App Store applicabili. Il contenuto Web è ospitato all'interno di un controllo visualizzazione Web nativo e viene eseguito nel contesto dell'app. Qualsiasi parte dell'app può accedere a servizi Web esterni, ma non è necessaria.

Per altre informazioni, vedere HybridWebView.

Barra del titolo per Windows

Il TitleBar controllo consente di aggiungere una barra del titolo personalizzata all'app in Windows:

Panoramica della barra del titolo .NET MAUI.

Un TitleBar oggetto può essere impostato come valore della Window.TitleBar proprietà in qualsiasi TitleBaroggetto :

<Window.TitleBar>
    <TitleBar x:Name="TeamsTitleBar"
              Title="Hello World"
              Icon="appicon.png"
              HeightRequest="46">
        <TitleBar.Content>
            <SearchBar Placeholder="Search"
                       PlaceholderColor="White"
                       MaximumWidthRequest="300"
                       HorizontalOptions="Fill"
                       VerticalOptions="Center" />
        </TitleBar.Content>
    </TitleBar>
</Window.TitleBar>

Un esempio dell'uso in C# è:

Window window = new Window
{
    TitleBar = new TitleBar
    {
        Icon = "titlebar_icon.png"
        Title = "My App",
        Subtitle = "Demo"
        Content = new SearchBar { ... }      
    }
};

Un TitleBar oggetto è altamente personalizzabile tramite le relative Contentproprietà , LeadingContente TrailingContent :

<TitleBar Title="My App"
          BackgroundColor="#512BD4"
          HeightRequest="48">
    <TitleBar.Content>
        <SearchBar Placeholder="Search"
                   MaximumWidthRequest="300"
                   HorizontalOptions="Fill"
                   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>

Lo screenshot seguente mostra l'aspetto risultante:

Screenshot della barra del titolo .NET MAUI.

Nota

Il supporto di Mac Catalyst per il TitleBar controllo verrà aggiunto in una versione futura.

Per altre informazioni, vedere TitleBar.

Miglioramenti del controllo

.NET MAUI 9 include miglioramenti del controllo.

Modalità di associazione BackButtonBehavior OneWay

La modalità di BindingMode.OneTimeassociazione per IsVisible e IsEnabled in un BackButtonBehavior in un'app Shell è ora BindingMode.OneWay anziché . In questo modo è possibile controllare più facilmente il comportamento del pulsante Indietro in fase di esecuzione, con i data binding:

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

BlazorWebView

In iOS e Mac Catalyst 18, .NET MAUI 9 modifica il comportamento predefinito per l'hosting del contenuto in un BlazorWebView oggetto in localhost. L'indirizzo interno 0.0.0.1 usato per ospitare il contenuto non funziona più e comporta il BlazorWebView mancato caricamento di alcun contenuto e il rendering come rettangolo vuoto.

Per acconsentire esplicitamente all'uso dell'indirizzo 0.0.0.1 , aggiungere il codice seguente al CreateMauiApp metodo in MauiProgram.cs:

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

Per impostazione predefinita, BlazorWebView ora viene attivato e dimentica l'eliminazione asincrona dell'oggetto sottostante WebViewManager. In questo modo si riduce il rischio che si verifichino deadlock di eliminazione in Android.

Avviso

Questo comportamento predefinito fire-and-forget significa che lo smaltimento può restituire prima che tutti gli oggetti vengano eliminati, che possono causare modifiche comportamentali nell'app. Gli elementi eliminati sono tipi interni di Blazor parzialmente personalizzati, ma anche tipi definiti dall'app, ad esempio i servizi con ambito usati all'interno della BlazorWebView parte dell'app.

Per rifiutare esplicitamente questo comportamento, è necessario configurare l'app per bloccare l'eliminazione tramite un'opzione AppContext nel CreateMauiApp metodo nella MauiProgram classe:

AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", false);

Se l'app è configurata per bloccare l'eliminazione tramite questa opzione, BlazorWebView esegue l'eliminazione asincrona tramite sincronizzazione, il che significa che blocca il thread fino al completamento dell'eliminazione asincrona. Tuttavia, questo può causare deadlock se l'eliminazione deve eseguire codice nello stesso thread (perché il thread è bloccato durante l'attesa).

Pulsanti in iOS

Button i controlli in iOS ora rispettano la spaziatura, la spaziatura interna, la larghezza del bordo e i margini in modo più accurato rispetto alle versioni precedenti. Un'immagine di grandi dimensioni in verrà Button ora ridimensionata in base alle dimensioni massime, tenendo conto della spaziatura, della spaziatura, della spaziatura interna, della larghezza del bordo e dei margini. Tuttavia, se un Button oggetto contiene testo e un'immagine potrebbe non essere possibile adattare tutto il contenuto all'interno del pulsante, quindi è consigliabile ridimensionare manualmente l'immagine per ottenere il layout desiderato.

CollectionView e CarouselView

.NET MAUI 9 include due nuovi gestori facoltativi in iOS e Mac Catalyst che apportano miglioramenti delle prestazioni e della stabilità a CollectionView e CarouselView. Questi gestori sono basati sulle UICollectionView API.

Per acconsentire esplicitamente all'uso di questi gestori, aggiungere il codice seguente alla MauiProgram classe :

#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

ContentPage

In .NET MAUI 9 la HideSoftInputOnTapped proprietà è supportata anche in Mac Catalyst, nonché in Android e iOS.

Supporto per l'input da tastiera flessibile

.NET MAUI 9 aggiunge il nuovo supporto per l'input della tastiera soft per Password, Datee Time. Questi controlli possono essere abilitati nei Editor controlli e Entry :

<Entry Keyboard="Date" />

Allineamento testo

L'enumerazione TextAlignment aggiunge un Justify membro che può essere utilizzato per allineare il testo nei controlli di testo. Ad esempio, è possibile allineare orizzontalmente il testo in un Label oggetto con HorizontalTextAlignment.Justify:

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

TimePicker

TimePicker ottiene un TimeSelected evento, che viene generato quando cambia l'ora selezionata. L'oggetto TimeChangedEventArgs che accompagna l'evento TimeSelected ha NewTime proprietà e OldTime , che specificano rispettivamente il nuovo e il tempo precedente.

WebView

WebView aggiunge un ProcessTerminated evento generato quando un WebView processo termina in modo imprevisto. L'oggetto WebViewProcessTerminatedEventArgs che accompagna questo evento definisce proprietà specifiche della piattaforma che indicano il motivo per cui il processo non è riuscito.

Associazioni compilate nel codice

Le associazioni scritte nel codice usano in genere percorsi stringa risolti in fase di esecuzione con reflection e il sovraccarico di questa operazione varia da piattaforma a piattaforma. .NET MAUI 9 introduce un metodo di estensione aggiuntivo SetBinding che definisce le associazioni usando un Func argomento anziché un percorso stringa:

// in .NET 8
MyLabel.SetBinding(Label.TextProperty, "Text");

// in .NET 9
MyLabel.SetBinding(Label.TextProperty, static (Entry entry) => entry.Text);

Questo approccio di binding compilato offre i vantaggi seguenti:

  • Miglioramento delle prestazioni del data binding risolvendo le espressioni di binding in fase di compilazione anziché in fase di esecuzione.
  • Un'esperienza migliore per la risoluzione dei problemi per gli sviluppatori perché le associazioni non valide vengono segnalate come errori di compilazione.
  • IntelliSense durante la modifica.

Non tutti i metodi possono essere usati per definire un'associazione compilata. L'espressione deve essere un'espressione di accesso alle proprietà semplice. Gli esempi seguenti mostrano espressioni di associazione valide e non valide:

// Valid: Property access
static (PersonViewModel vm) => vm.Name;
static (PersonViewModel vm) => vm.Address?.Street;

// Valid: Array and indexer access
static (PersonViewModel vm) => vm.PhoneNumbers[0];
static (PersonViewModel vm) => vm.Config["Font"];

// Valid: Casts
static (Label label) => (label.BindingContext as PersonViewModel).Name;
static (Label label) => ((PersonViewModel)label.BindingContext).Name;

// Invalid: Method calls
static (PersonViewModel vm) => vm.GetAddress();
static (PersonViewModel vm) => vm.Address?.ToString();

// Invalid: Complex expressions
static (PersonViewModel vm) => vm.Address?.Street + " " + vm.Address?.City;
static (PersonViewModel vm) => $"Name: {vm.Name}";

.NET MAUI 9 aggiunge inoltre un BindingBase.Create metodo che imposta l'associazione direttamente sull'oggetto con un Funce restituisce l'istanza dell'oggetto di associazione:

// in .NET 8
myEntry.SetBinding(Entry.TextProperty, new MultiBinding
{
    Bindings = new Collection<BindingBase>
    {
        new Binding(nameof(Entry.FontFamily), source: RelativeBindingSource.Self),
        new Binding(nameof(Entry.FontSize), source: RelativeBindingSource.Self),
        new Binding(nameof(Entry.FontAttributes), source: RelativeBindingSource.Self),
    },
    Converter = new StringConcatenationConverter()
});

// in .NET 9
myEntry.SetBinding(Entry.TextProperty, new MultiBinding
{
    Bindings = new Collection<BindingBase>
    {
        Binding.Create(static (Entry entry) => entry.FontFamily, source: RelativeBindingSource.Self),
        Binding.Create(static (Entry entry) => entry.FontSize, source: RelativeBindingSource.Self),
        Binding.Create(static (Entry entry) => entry.FontAttributes, source: RelativeBindingSource.Self),
    },
    Converter = new StringConcatenationConverter()
});

Importante

Le associazioni compilate sono necessarie invece di associazioni basate su stringhe nelle app NativeAOT e nelle app con taglio completo abilitato.

Binding compilati in XAML

In .NET MAUI 8, le associazioni compilate sono disabilitate per tutte le espressioni di associazione XAML che definiscono la Source proprietà e non sono supportate su più associazioni. Queste restrizioni sono state rimosse in .NET MAUI 9. Per informazioni sulla compilazione di espressioni di associazione XAML che definiscono la Source proprietà, vedere Compilazione di associazioni che definiscono la Source proprietà.

Per impostazione predefinita, .NET MAUI 9 genera avvisi di compilazione per le associazioni che non usano associazioni compilate. Per altre informazioni sugli avvisi dei binding compilati xaml, vedi Avvisi di binding compilati xaml.

Inserimento delle dipendenze

In un'app Shell non è più necessario registrare le pagine con il contenitore di inserimento delle dipendenze, a meno che non si voglia influenzare la durata della pagina rispetto al contenitore con i AddSingletonmetodi , AddTransiento AddScoped . Per altre informazioni su questi metodi, vedere Durata delle dipendenze.

Disconnessione del gestore

Quando si implementa un controllo personalizzato tramite gestori, ogni implementazione del gestore della piattaforma è necessaria per implementare il DisconnectHandler() metodo , per eseguire qualsiasi pulizia della visualizzazione nativa, ad esempio annullare la sottoscrizione dagli eventi. Tuttavia, prima di .NET MAUI 9, l'implementazione DisconnectHandler() non viene intenzionalmente richiamata da .NET MAUI. È invece necessario richiamarlo manualmente quando si sceglie di pulire un controllo, ad esempio quando si passa all'indietro in un'app.

In .NET MAUI 9 i gestori si disconnettono automaticamente dai controlli quando possibile, ad esempio quando si sposta all'indietro in un'app. In alcuni scenari potrebbe non essere necessario questo comportamento. Pertanto, .NET MAUI 9 aggiunge una HandlerProperties.DisconnectPolicy proprietà associata per il controllo quando i gestori vengono disconnessi dai relativi controlli. Questa proprietà richiede un HandlerDisconnectPolicy argomento, con l'enumerazione che definisce i valori seguenti:

  • Automatic, che indica che i gestori verranno disconnessi automaticamente. Questo è il valore predefinito della proprietà associata HandlerProperties.DisconnectPolicy.
  • Manual, che indica che i gestori dovranno essere disconnessi manualmente richiamando l'implementazione DisconnectHandler() .

Nell'esempio seguente viene illustrata l'impostazione della HandlerProperties.DisconnectPolicy proprietà associata:

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

Il codice C# equivalente è il seguente:

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

È inoltre disponibile un DisconnectHandlers metodo di estensione che disconnette i gestori da un determinato IViewoggetto :

video.DisconnectHandlers();

Quando si disconnette, il DisconnectHandlers metodo si propaga verso il basso nell'albero dei controlli finché non viene completato o arriva a un controllo che ha impostato un criterio manuale.

Supporto per più finestre

.NET MAUI 9 aggiunge la possibilità di portare una finestra specifica davanti a Mac Catalyst e Windows con il Application.Current.ActivateWindow metodo :

Application.Current?.ActivateWindow(windowToActivate);

Distribuzione AOT nativa

In .NET MAUI 9 è possibile acconsentire esplicitamente alla distribuzione AOT nativa in iOS e Mac Catalyst. La distribuzione AOT nativa produce un'app MAUI .NET che è stata compilata in anticipo (AOT) nel codice nativo. Ciò produce i vantaggi seguenti:

  • Riduzione delle dimensioni del pacchetto dell'app, in genere fino a 2,5 volte inferiore.
  • Tempo di avvio più veloce, in genere fino a 2 volte più veloce.
  • Tempo di compilazione più rapido.

Per altre informazioni, vedere Distribuzione AOT nativa in iOS e Mac Catalyst.

Incorporamento nativo

.NET MAUI 9 include API complete per scenari di incorporamento nativi, che in precedenza dovevano essere aggiunti manualmente al progetto:

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);

In alternativa, è possibile usare il ToPlatformEmbedded metodo , passando per Window la piattaforma in cui è in esecuzione l'app:

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

In entrambi gli esempi è nativeView una versione specifica della piattaforma di mauiView.

Per avviare un'app incorporata nativa in .NET MAUI 9, chiamare il metodo di estensione sull'oggetto UseMauiEmbeddedApp MauiAppBuilder :

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

        builder
            .UseMauiEmbeddedApp<App>();

        return builder.Build();
    }
}

Per altre informazioni, vedere Incorporamento nativo.

Modelli di progetto

Il modello di progetto .NET MAUI App include la possibilità di creare un'app todo completamente funzionale, usando i controlli di Syncfusion Toolkit per .NET MAUI per visualizzare i dati e renderli persistenti in un database locale basato su SQLite. Per creare questa app todo, creare un nuovo progetto in Visual Studio usando il modello di progetto .NET MAUI App e quindi selezionare la casella di controllo Includi contenuto di esempio nella finestra Informazioni aggiuntive:

Screenshot di come aggiungere pagine di esempio SyncFusion al progetto di app MAUI .NET.

L'app todo può essere creata anche dall'interfaccia della riga di comando di .NET con l'opzione --sample-content o -sc :

dotnet new maui --sample-content -n MyProject

.NET MAUI 9 aggiunge anche un modello di progetto .NET MAUI Blazor Ibrido e App Web a Visual Studio che crea una soluzione con un'app ibrida Blazor MAUI .NET con un'app Web Blazor, che condividono codice comune in un progetto di libreria di classi Razor.

Il modello può essere usato anche dall'interfaccia della riga di comando di .NET:

dotnet new maui-blazor-web -n MyProject

Dizionari risorse

In .NET MAUI 9, un xaml ResourceDictionary autonomo (che non è supportato da un file code-behind) per impostazione predefinita ha il relativo codice XAML compilato. Per rifiutare esplicitamente questo comportamento, specificare <?xaml-comp compile="false" ?> dopo l'intestazione XML.

Trimming

Il taglio completo è ora supportato impostando la $(TrimMode) proprietà MSBuild su full. Per altre informazioni, vedere Tagliare un'app MAUI .NET.

Incompatibilità di taglio

Le seguenti funzionalità MAUI .NET non sono compatibili con il taglio completo e verranno rimosse dal trimmer:

Interruttori delle funzionalità di taglio

.NET MAUI include direttive trimmer, note come commutatori di funzionalità, che consentono di mantenere il codice per le funzionalità che non sono sicure. Queste direttive trimmer possono essere usate quando la proprietà di $(TrimMode) compilazione è impostata su full, nonché per Native AOT:

Proprietà MSBuild Descrizione
MauiEnableVisualAssemblyScanning Se impostato su true, .NET MAUI analizzerà gli assembly per individuare i tipi che implementano IVisual e per [assembly:Visual(...)] gli attributi e registrerà questi tipi. Per impostazione predefinita, questa proprietà di compilazione è impostata su false quando è abilitato il taglio completo.
MauiShellSearchResultsRendererDisplayMemberNameSupported Se impostato su false, il valore di SearchHandler.DisplayMemberName verrà ignorato. È invece necessario fornire un oggetto ItemTemplate per definire l'aspetto dei SearchHandler risultati. Per impostazione predefinita, questa proprietà di compilazione è impostata su false quando è abilitato il taglio completo o Native AOT.
MauiQueryPropertyAttributeSupport Se impostato su false, [QueryProperty(...)] gli attributi non verranno usati per impostare i valori delle proprietà durante lo spostamento. È invece necessario implementare l'interfaccia IQueryAttributable per accettare i parametri di query. Per impostazione predefinita, questa proprietà di compilazione è impostata su false quando è abilitato il taglio completo o Native AOT.
MauiImplicitCastOperatorsUsageViaReflectionSupport Se impostato su false, .NET MAUI non cercherà gli operatori di conversione impliciti durante la conversione di valori da un tipo a un altro. Ciò può influire sulle associazioni tra le proprietà con tipi diversi e l'impostazione di un valore della proprietà di un oggetto associabile con un valore di un tipo diverso. È invece necessario definire un TypeConverter oggetto per il tipo e collegarlo al tipo usando l'attributo TypeConverterAttribute . Per impostazione predefinita, questa proprietà di compilazione è impostata su false quando è abilitato il taglio completo o Native AOT.
_MauiBindingInterceptorsSupport Se impostato su false, .NET MAUI non intercetta alcuna chiamata ai SetBinding metodi e non tenterà di compilarli. Per impostazione predefinita, questa proprietà di compilazione è impostata su true.
MauiEnableXamlCBindingWithSourceCompilation Se impostato su true, .NET MAUI compilerà tutte le associazioni, incluse quelle in cui viene usata la Source proprietà . Se si abilita questa funzionalità, assicurarsi che tutte le associazioni siano corrette x:DataType in modo che vengano compilate o cancellate il tipo di dati con x:Data={x:Null}} se l'associazione non deve essere compilata. Per impostazione predefinita, questa proprietà di compilazione è impostata su true quando è abilitato il taglio completo o Native AOT.
MauiHybridWebViewSupported Se impostato su false, il HybridWebView controllo non sarà disponibile. Per impostazione predefinita, questa proprietà di compilazione è impostata su false quando è abilitato il taglio completo o Native AOT.

Queste proprietà di MSBuild hanno anche opzioni equivalenti AppContext :

  • La MauiEnableVisualAssemblyScanning proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.IsIVisualAssemblyScanningEnabled.
  • La MauiShellSearchResultsRendererDisplayMemberNameSupported proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.IsShellSearchResultsRendererDisplayMemberNameSupported.
  • La MauiQueryPropertyAttributeSupport proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.IsQueryPropertyAttributeSupported.
  • La MauiImplicitCastOperatorsUsageViaReflectionSupport proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.IsImplicitCastOperatorsUsageViaReflectionSupported.
  • La _MauiBindingInterceptorsSupport proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.AreBindingInterceptorsSupported.
  • La MauiEnableXamlCBindingWithSourceCompilation proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.MauiEnableXamlCBindingWithSourceCompilationEnabled.
  • La MauiHybridWebViewSupported proprietà MSBuild ha un'opzione equivalente denominata AppContext Microsoft.Maui.RuntimeFeature.IsHybridWebViewSupported.

Il modo più semplice per usare un commutatore di funzionalità consiste nell'inserire la proprietà MSBuild corrispondente nel file di progetto dell'app (*.csproj), che causa il taglio del codice correlato dagli assembly MAUI .NET.

Distribuzione di app di Windows

Quando si esegue il debug e si distribuisce un nuovo progetto MAUI .NET in Windows, il comportamento predefinito in .NET MAUI 9 consiste nel distribuire un'app non in pacchetto. Per altre informazioni, vedere Distribuire ed eseguire il debug dell'app .NET MAUI in Windows.

Codici di errore del compilatore XAML

In .NET MAUI 9 i codici di errore del compilatore XAML hanno modificato il prefisso da XFC a XC. Assicurarsi di aggiornare le $(WarningsAsErrors)proprietà di compilazione , $(WarningsNotAsErrors)e $(NoWarn) nei file di progetto dell'app, se usata, per fare riferimento al nuovo prefisso.

Estensioni di markup XAML

Tutte le classi che implementano IMarkupExtension, IValueProviderIMarkupExtension<T>, e IExtendedTypeConverter devono essere annotate con o RequireServiceAttribute AcceptEmptyServiceProviderAttribute. Questa operazione è necessaria a causa di un'ottimizzazione del compilatore XAML introdotta in .NET MAUI 9 che consente la generazione di codice più efficiente, che consente di ridurre le dimensioni dell'app e migliorare le prestazioni di runtime.

Per informazioni sull'annotazione delle estensioni di markup con questi attributi, vedere Provider di servizi.

Sincronizzazione Xcode

.NET MAUI 9 include la sincronizzazione Xcode (xcsync), uno strumento che consente di usare Xcode per la gestione di file specifici di Apple con progetti .NET, inclusi cataloghi di asset, file plist, storyboard e file xib. Lo strumento include due comandi principali per generare un progetto Xcode temporaneo da un progetto .NET e per sincronizzare le modifiche dai file Xcode al progetto .NET.

dotnet build Usare con i xcsync-generate comandi o xcsync-sync per generare o sincronizzare questi file e passare un file di progetto e argomenti aggiuntivi:

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

Per altre informazioni, vedere Sincronizzazione Xcode.

API deprecate

.NET MAUI 9 depreca alcune API, che verranno rimosse completamente in una versione futura.

Frame

Il Frame controllo è contrassegnato come obsoleto in .NET MAUI 9 e verrà rimosso completamente in una versione futura. Il Border controllo deve essere utilizzato al suo posto. Per altre informazioni, vedere Border.

MainPage

Invece di definire la prima pagina dell'app usando la MainPage proprietà in un Application oggetto, devi impostare la Page proprietà su una Window sulla prima pagina dell'app. Questo è ciò che accade internamente in .NET MAUI quando si imposta la MainPage proprietà, quindi non viene apportata alcuna modifica di comportamento introdotta dalla MainPage proprietà contrassegnata come obsoleta.

Nell'esempio seguente viene illustrata l'impostazione della Page proprietà su un Windowoggetto tramite l'override CreateWindow :

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

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

Il codice che accede alla Application.Current.MainPage proprietà dovrebbe ora accedere alla Application.Current.Windows[0].Page proprietà per le app con una singola finestra. Per le app con più finestre, usare la Application.Current.Windows raccolta per identificare la finestra corretta e quindi accedere alla Page proprietà . Inoltre, ogni elemento include una Window proprietà, accessibile quando l'elemento fa parte della finestra corrente, da cui è possibile accedere alla Page proprietà (Window.Page). Il codice della piattaforma può recuperare l'oggetto dell'app IWindow con il Microsoft.Maui.Platform.GetWindow metodo di estensione.

Mentre la MainPage proprietà viene mantenuta in .NET MAUI 9, verrà rimossa completamente in una versione futura.

Layout di compatibilità

Le classi di layout di compatibilità nello spazio dei Microsoft.Maui.Controls.Compatibility nomi sono obsolete.

Chiamate di misura legacy

I metodi di misura seguenti VisualElement sono obsoleti:

Si tratta di metodi di misura legacy che non funzionano correttamente con le aspettative di layout MAUI .NET.

In sostituzione, è stato introdotto il VisualElement.Measure(Double, Double) metodo . Questo metodo restituisce le dimensioni minime necessarie per visualizzare un elemento in un dispositivo. I margini vengono esclusi dalla misura, ma vengono restituiti con le dimensioni. Questo è il metodo preferito da chiamare durante la misurazione di una vista.

Inoltre, lo SizeRequest struct è obsoleto. È invece Size consigliabile usare .

Eseguire l'aggiornamento da .NET 8 a .NET 9

Per aggiornare i progetti MAUI .NET da .NET 8 a .NET 9, installare prima .NET 9 e il carico di lavoro MAUI .NET con Visual Studio 17.12 o con Visual Studio Code e l'estensione MAUI .NET e .NET e i carichi di lavoro MAUI .NET o con il programma di installazione autonomo e il dotnet workload install maui comando.

Aggiornare il file di progetto

Per aggiornare l'app .NET MAUI da .NET 8 a .NET 9, aprire il file di progetto dell'app (con estensione csproj) e modificare i moniker (TFM) di Target Framework da 8 a 9. Se si usa un TFM, net8.0-ios15.2 ad esempio assicurarsi di corrispondere alla versione della piattaforma o rimuoverla completamente. L'esempio seguente illustra i TFM per un progetto .NET 8:

<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst;net8.0-tizen</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>

L'esempio seguente illustra i TFM per un progetto .NET 9:

<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst;net9.0-tizen</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>

Se il file di progetto dell'app fa riferimento a una versione .NET 8 del Microsoft.Maui.Controls pacchetto NuGet, direttamente o tramite la $(MauiVersion) proprietà di compilazione, aggiornare questa opzione a una versione .NET 9. Rimuovere quindi il riferimento al pacchetto NuGet per il Microsoft.Maui.Controls.Compatibility pacchetto NuGet, a condizione che l'app non usi alcun tipo da questo pacchetto. Aggiornare anche il riferimento al pacchetto NuGet Microsoft.Extensions.Logging.Debug alla versione più recente di .NET 9.

Se l'app è destinata a iOS o Mac Catalyst, aggiornare le proprietà di $(SupportedOSPlatformVersion) compilazione per queste piattaforme alla versione 15.0:

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>

Quando si esegue il debug e si distribuisce un nuovo progetto MAUI .NET in Windows, il comportamento predefinito in .NET 9 consiste nel distribuire un'app non in pacchetto. Per adottare questo comportamento, vedere Convertire un'app windows .NET maUI in pacchetto in un pacchetto.

Prima di compilare l'app aggiornata per la prima volta, eliminare le bin cartelle e obj . Eventuali errori e avvisi di compilazione consentiranno di procedere con i passaggi successivi.

Aggiornare i codici di errore del compilatore XAML

I codici di errore del compilatore XAML hanno modificato il prefisso da XFC a XC, quindi aggiornare le $(WarningsAsErrors)proprietà di compilazione , $(WarningsNotAsErrors)e $(NoWarn) nel file di progetto dell'app, se usato, per fare riferimento al nuovo prefisso.

Risolvere i nuovi avvisi del compilatore XAML per le associazioni compilate

Gli avvisi di compilazione verranno generati per le associazioni che non usano associazioni compilate e che dovranno essere risolte. Per altre informazioni, vedi Avvisi di binding compilati xaml.

Aggiornare le estensioni di markup XAML

Le estensioni di markup XAML dovranno essere annotate con o RequireServiceAttribute AcceptEmptyServiceProviderAttribute. Questa operazione è necessaria a causa di un'ottimizzazione del compilatore XAML che consente la generazione di codice più efficiente, che consente di ridurre le dimensioni dell'app e migliorare le prestazioni di runtime. Per altre informazioni, vedere Provider di servizi.

API deprecate degli indirizzi

.NET MAUI 9 depreca alcune API, che verranno rimosse completamente in una versione futura. Di conseguenza, risolvere eventuali avvisi di compilazione sulle API deprecate. Per altre informazioni, vedere API deprecate.

Adottare associazioni compilate che impostano la proprietà Source

È possibile acconsentire esplicitamente alla compilazione di associazioni che impostano la Source proprietà per sfruttare le prestazioni di runtime migliori. Per altre informazioni, vedere Compilazione di associazioni che definiscono la Source proprietà .

Adottare associazioni compilate in C#

È possibile acconsentire esplicitamente alla compilazione di espressioni di binding dichiarate nel codice per sfruttare le prestazioni di runtime migliori. Per altre informazioni, vedere Binding compilati nel codice.

Adottare il taglio completo

È possibile adottare l'uso del taglio completo per ridurre le dimensioni complessive dell'app impostando la $(TrimMode) proprietà MSBuild su full. Per altre informazioni, vedere Tagliare un'app MAUI .NET.

Adottare la distribuzione NativeAOT nelle piattaforme supportate

È possibile acconsentire esplicitamente alla distribuzione AOT nativa in iOS e Mac Catalyst. La distribuzione AOT nativa produce un'app MAUI .NET che è stata compilata in anticipo (AOT) nel codice nativo. Per altre informazioni, vedere Distribuzione AOT nativa in iOS e Mac Catalyst.

.NET per Android

.NET per Android in .NET 9, che aggiunge il supporto per l'API 35, include il lavoro per ridurre i tempi di compilazione e migliorare la taglia delle app per ridurre le dimensioni e migliorare le prestazioni. Per altre informazioni su .NET per Android in .NET 9, vedere le note sulla versione seguenti:

Pacchetti di asset

.NET per Android in .NET 9 introduce la possibilità di inserire gli asset in un pacchetto separato, noto come asset pack. Ciò consente di caricare giochi e app che normalmente sarebbero maggiori delle dimensioni del pacchetto di base consentite da Google Play. Inserendo questi asset in un pacchetto separato si ottiene la possibilità di caricare un pacchetto con dimensioni fino a 2 GB, anziché le dimensioni di base del pacchetto di 200 Mb.

Importante

I pacchetti di asset possono contenere solo asset. Nel caso di .NET per Android questo significa che gli elementi con l'azione AndroidAsset di compilazione.

Le app MAUI .NET definiscono gli asset tramite l'azione di MauiAsset compilazione. È possibile specificare un asset pack tramite l'attributo AssetPack :

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

Nota

I metadati aggiuntivi verranno ignorati da altre piattaforme.

Se si hanno elementi specifici da inserire in un asset pack, è possibile usare l'attributo Update per definire i AssetPack metadati:

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

I pacchetti asset possono avere diverse opzioni di recapito, che controllano quando gli asset verranno installati nel dispositivo:

  • I time pack di installazione vengono installati contemporaneamente all'app. Questo tipo di pacchetto può avere dimensioni fino a 1 GB, ma è possibile avere solo una di esse. Questo tipo di recapito viene specificato con InstallTime i metadati.
  • I pacchetti di follow pack rapidi verranno installati a un certo punto poco dopo il completamento dell'installazione dell'app. L'app sarà in grado di iniziare durante l'installazione di questo tipo di pacchetto in modo da verificare che sia stata completata l'installazione prima di provare a usare gli asset. Questo tipo di asset pack può avere dimensioni fino a 512 Mb. Questo tipo di recapito viene specificato con FastFollow i metadati.
  • I pacchetti su richiesta non verranno mai scaricati nel dispositivo, a meno che l'app non la richieda in modo specifico. Le dimensioni totali di tutti i pacchetti di asset non possono superare i 2 GB ed è possibile avere fino a 50 pacchetti di asset separati. Questo tipo di recapito viene specificato con OnDemand i metadati.

Nelle app MAUI .NET è possibile specificare il tipo di recapito con l'attributo DeliveryType in :MauiAsset

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

Per altre informazioni sui pacchetti di asset Android, vedere Asset Pack Android.

Supporto di Android 15

.NET per Android in .NET 9 aggiunge associazioni .NET per Android 15 (API 35). Per compilare per queste API, aggiornare il framework di destinazione del progetto in net9.0-android:

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

Nota

È anche possibile specificare net9.0-android35 come framework di destinazione, ma il numero 35 probabilmente cambierà nelle versioni future di .NET in modo che corrispondano alle versioni più recenti del sistema operativo Android.

Architetture a 64 bit per impostazione predefinita

.NET per Android in .NET 9 non compila più gli identificatori di runtime (RID) seguenti per impostazione predefinita:

  • android-arm
  • android-x86

Questo dovrebbe migliorare i tempi di compilazione e ridurre le dimensioni dei file Android .apk . Si noti che Google Play supporta la suddivisione dei bundle di app per ogni architettura.

Se è necessario compilare per queste architetture, è possibile aggiungerle al file di progetto (con estensione csproj):

<RuntimeIdentifiers>android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>

In alternativa, in un progetto multi-destinazione:

<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>

Metodi di marshalling Android

I miglioramenti apportati ai metodi di marshalling di Android in .NET 9 hanno reso la funzionalità più affidabile nelle applicazioni, ma non è ancora l'impostazione predefinita. L'abilitazione di questa funzionalità ha comportato un miglioramento del 10% delle prestazioni in un'app di test.

I metodi di marshalling Android possono essere abilitati nel file di progetto (con estensione csproj) tramite la $(AndroidEnableMarshalMethods) proprietà :

<PropertyGroup>
    <AndroidEnableMarshalMethods>true</AndroidEnableMarshalMethods>
</PropertyGroup>

Per informazioni specifiche sulla funzionalità, vedere la documentazione o l'implementazione delle funzionalità in GitHub.

Miglioramenti del taglio

In .NET 9 gli assembly DELL'API Android (Mono.Android.dll, Java.Interop.dll) sono ora completamente compatibili. Per acconsentire esplicitamente al taglio completo, impostare la $(TrimMode) proprietà nel file di progetto (con estensione csproj):

<PropertyGroup>
    <TrimMode>Full</TrimMode>
</PropertyGroup>

Ciò consente anche di tagliare gli analizzatori, in modo che vengano introdotti avvisi per qualsiasi codice C# problematico.

Per altre informazioni, vedere Granularità di taglio.

.NET per iOS

.NET 9 in iOS, tvOS, Mac Catalyst e macOS usa Xcode 16.0 per le versioni della piattaforma seguenti:

  • iOS: 18.0
  • tvOS: 18.0
  • Mac Catalyst: 18.0
  • macOS: 15.0

Per altre informazioni su .NET 9 in iOS, tvOS, Mac Catalyst e macOS, vedere le note sulla versione seguenti:

Bindings

.NET per iOS 9 introduce la possibilità di usare versioni multi target di .NET per le associazioni iOS. Ad esempio, potrebbe essere necessario compilare un progetto di libreria per due versioni iOS distinte:

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

Verranno prodotte due librerie, una con binding iOS 17.0 e una usando le associazioni iOS 17.2.

Importante

Un progetto di app deve sempre avere come destinazione l'SDK iOS più recente.

Miglioramenti del taglio

In .NET 9 gli assembly iOS e Mac Catalyst (Microsoft.iOS.dll, Microsoft.MacCatalyst.dll e così via) sono ora completamente compatibili con il taglio. Per acconsentire esplicitamente al taglio completo, impostare la $(TrimMode) proprietà nel file di progetto (con estensione csproj):

<PropertyGroup>
    <TrimMode>Full</TrimMode>
</PropertyGroup>

Ciò consente anche di tagliare gli analizzatori, in modo che vengano introdotti avvisi per qualsiasi codice C# problematico.

Per altre informazioni, vedere Granularità di taglio.

AOT nativo per iOS e Mac Catalyst

In .NET per iOS 9 la compilazione nativa di Ahead of Time (AOT) per iOS e Mac Catalyst sfrutta il taglio completo per ridurre le dimensioni del pacchetto e le prestazioni di avvio dell'app. NativeAOT si basa sul taglio completo, optando anche per un nuovo runtime.

Importante

L'app e le dipendenze devono essere completamente trimmabili per poter usare questa funzionalità.

NativeAOT richiede che le applicazioni vengano compilate con avvisi senza trimmer, per dimostrare che l'applicazione funzionerà correttamente in fase di esecuzione.

Vedi anche