Partilhar via


O que há de novo no .NET MAUI para .NET 9

O foco do .NET Multi-platform App UI (.NET MAUI) no .NET 9 é melhorar a qualidade do produto. Isso inclui a expansão da cobertura de testes, testes de cenário de ponta a ponta e correção de bugs. Para obter mais informações sobre as melhorias de qualidade do produto no .NET MAUI 9, consulte as seguintes notas de versão:

Importante

Devido ao trabalho com dependências externas, como Xcode ou Android SDK Tools, a política de suporte do .NET MAUI difere da política de suporte do .NET e .NET Core. Para mais informações, consulte a política de suporte do .NET MAUI.

A compatibilidade com o Xcode 16, que inclui suporte a SDK para iOS 18, iPadOS 18, tvOS 18 e macOS 15, é necessária ao criar com o .NET MAUI 9. O Xcode 16 requer um Mac com macOS 14.5 ou posterior.

No .NET 9, o .NET MAUI é disponibilizado como uma carga de trabalho do .NET e através de vários pacotes NuGet. A vantagem dessa abordagem é que ela permite que você fixe facilmente seus projetos em versões específicas, ao mesmo tempo em que permite visualizar facilmente compilações não lançadas ou experimentais. Quando você cria um novo projeto .NET MAUI, os pacotes NuGet necessários são adicionados automaticamente ao projeto.

Metas mínimas de implantação

O .NET MAUI 9 requer destinos mínimos de implantação do iOS 12.2 e do Mac Catalyst 15.0 (macOS 12.0). As metas mínimas de implantação do Android e do Windows permanecem as mesmas. Para obter mais informações, consulte Plataformas suportadas para aplicativos .NET MAUI.

Novos controlos

O .NET MAUI 9 inclui dois novos controles.

HybridWebView

HybridWebView permite hospedar conteúdo HTML/JS/CSS arbitrário em uma exibição da Web e permite a comunicação entre o código na exibição da Web (JavaScript) e o código que hospeda a exibição da Web (C#/.NET). Por exemplo, se você tiver um aplicativo React JS existente, poderá hospedá-lo em um aplicativo nativo .NET MAUI de plataforma cruzada e criar o back-end do aplicativo usando C# e .NET.

Para criar um aplicativo .NET MAUI com HybridWebView você precisa:

  • O conteúdo da Web do aplicativo, que consiste em HTML estático, JavaScript, CSS, imagens e outros arquivos.
  • Um controle HybridWebView como parte da interface do usuário do aplicativo. Isso pode ser conseguido fazendo referência a ele no XAML do aplicativo.
  • Código no conteúdo da Web e em C#/.NET, que usa as APIs HybridWebView para enviar mensagens entre os dois componentes.

Todo o aplicativo, incluindo o conteúdo da Web, é empacotado e executado localmente em um dispositivo, e pode ser publicado em lojas de aplicativos aplicáveis. O conteúdo da Web é hospedado em um controle de exibição da Web nativo e é executado dentro do contexto do aplicativo. Qualquer parte da aplicação pode aceder a serviços Web externos, mas não é obrigada a fazê-lo.

Para obter mais informações, consulte HybridWebView.

Barra de título para Windows

O controle TitleBar fornece a capacidade de adicionar uma barra de título personalizada ao seu aplicativo no Windows:

Visão geral da barra de título do .NET MAUI.

Um TitleBar pode ser definido como o valor da propriedade Window.TitleBar em qualquer TitleBar:

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

Um exemplo de seu uso em C# é:

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

Um TitleBar é altamente personalizável através de suas propriedades Content, 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>

A captura de tela a seguir mostra a aparência resultante:

captura de tela da barra de título do .NET MAUI.

Observação

O suporte do Mac Catalyst para o controle de TitleBar será adicionado em uma versão futura.

Para obter mais informações, consulte TitleBar.

Aprimoramentos de controle

O .NET MAUI 9 inclui aprimoramentos de controle.

ComportamentoDoBotãoVoltar modo de vinculação unidirecional

O modo de ligação para IsVisible e IsEnabled num BackButtonBehavior numa app Shell agora está BindingMode.OneWay em vez de BindingMode.OneTime. Isso permite que você controle mais facilmente o comportamento do botão Voltar em tempo de execução, com associações de dados:

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

BlazorWebView

O comportamento padrão para hospedar conteúdo em um BlazorWebView foi alterado para 0.0.0.1. O endereço interno 0.0.0.0 utilizado para hospedar conteúdo já não funciona, resultando em o BlazorWebView não carregar qualquer conteúdo e apresentando-se como um retângulo vazio.

Para optar por usar o endereço 0.0.0.0, adicione o seguinte código ao método CreateMauiApp em MauiProgram.cs:

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

Por padrão, BlazorWebView agora é acionado e esquece o descarte assíncrono do WebViewManagersubjacente. Isso reduz o potencial de ocorrerem bloqueios de descarte no Android.

Advertência

Esse comportamento padrão de disparar e esquecer significa que o descarte pode retornar antes que todos os objetos sejam descartados, o que pode causar alterações comportamentais em seu aplicativo. Os itens que são descartados são parcialmente tipos internos do próprio Blazor, mas também tipos definidos pelo aplicativo, como serviços 'scoped' utilizados na secção BlazorWebView do seu aplicativo.

Para desativar esse comportamento, você deve configurar seu aplicativo para bloquear ao descartar por meio de uma opção AppContext no método CreateMauiApp em sua classe MauiProgram:

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

Se a sua aplicação estiver configurada para bloquear na eliminação através deste interruptor, o BlazorWebView executa a eliminação assíncrona sincronizada, o que significa que bloqueia a thread até que a eliminação assíncrona esteja concluída. No entanto, isso pode causar deadlocks se o descarte precisar executar código no mesmo thread (porque o thread é bloqueado durante a espera).

Botões no iOS

Button controles no iOS agora respeitam espaçamento, preenchimento, largura da borda e margens com mais precisão do que nas versões anteriores. Uma imagem grande num Button agora será redimensionada para o tamanho máximo, levando em consideração o espaçamento, preenchimento, largura da borda e margens. No entanto, se um Button contiver texto e uma imagem, pode não ser possível encaixar todo o conteúdo dentro do botão, e assim você deve dimensionar sua imagem manualmente para alcançar o layout desejado.

CollectionView e CarouselView

O .NET MAUI 9 inclui dois novos manipuladores opcionais no iOS e Mac Catalyst que trazem melhorias de desempenho e estabilidade para CollectionView e CarouselView. Esses manipuladores são baseados em APIs UICollectionView.

Para optar por usar esses manipuladores, adicione o seguinte código à sua classe MauiProgram:

#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

Página de Conteúdo

No .NET MAUI 9, a propriedade HideSoftInputOnTapped também é suportada no Mac Catalyst, bem como no Android e iOS.

Suporte de entrada de teclado suave

.NET MAUI 9 adiciona novo suporte de entrada de teclado suave para Password, Datee Time. Estes podem ser ativados em controles Editor e Entry:

<Entry Keyboard="Date" />

Alinhamento do texto

A enumeração TextAlignment adiciona um membro Justify que pode ser usado para alinhar texto em controles de texto. Por exemplo, você pode alinhar horizontalmente o texto em um Label com HorizontalTextAlignment.Justify:

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

Seletor de Tempo

TimePicker ganha um evento TimeSelected, que é gerado quando a hora selecionada é alterada. O objeto TimeChangedEventArgs que acompanha o evento TimeSelected tem propriedades NewTime e OldTime, que especificam, respetivamente, o novo tempo e o antigo.

WebView

WebView adiciona um evento ProcessTerminated que é gerado quando um processo de WebView termina inesperadamente. O objeto WebViewProcessTerminatedEventArgs que acompanha esse evento define propriedades específicas da plataforma que indicam por que o processo falhou.

Ligações compiladas no código

As ligações escritas em código normalmente usam caminhos de cadeia de caracteres que são resolvidos em tempo de execução com reflexão, e a sobrecarga de fazer isso varia de plataforma para plataforma. .NET MAUI 9 introduz um método de extensão de SetBinding adicional que define ligações usando um argumento Func em vez de um caminho de cadeia de caracteres:

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

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

Esta abordagem vinculativa compilada oferece os seguintes benefícios:

  • Melhor desempenho de vinculação de dados resolvendo expressões de vinculação em tempo de compilação em vez de tempo de execução.
  • Uma melhor experiência de solução de problemas do desenvolvedor porque associações inválidas são relatadas como erros de compilação.
  • Intellisense durante a edição.

Nem todos os métodos podem ser usados para definir uma ligação compilada. A expressão deve ser uma expressão simples de acesso à propriedade. Os exemplos a seguir mostram expressões de vinculação válidas e inválidas:

// 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}";

Advertência

Um erro de compilador CS0272 ocorrerá se o acessador definido para uma propriedade ou indexador estiver inacessível. Se isso ocorrer, aumente a acessibilidade do acessório.

Além disso, o .NET MAUI 9 adiciona um método BindingBase.Create que define a ligação diretamente no objeto com um Funce retorna a instância do objeto de ligação:

// 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

Associações compiladas são necessárias em vez de associações baseadas em cadeia de caracteres em aplicativos NativeAOT e em aplicativos com corte completo habilitado.

Para obter mais informações sobre associações compiladas no código, consulte Ligações compiladas no código.

Associações compiladas em XAML

No .NET MAUI 8, as associações compiladas são desabilitadas para quaisquer expressões de associação XAML que definem a propriedade Source e não são suportadas em várias associações. Essas restrições foram removidas no .NET MAUI 9. Para obter informações sobre como compilar expressões de associação XAML que definem a propriedade Source, consulte Compile bindings that define the Source property.

Por padrão, o .NET MAUI 9 produz avisos de compilação para associações que não usam associações compiladas. Para obter mais informações sobre os avisos das associações compiladas do XAML, consulte os avisos das associações compiladas do XAML e.

Injeção de dependência

Em um aplicativo Shell, você não precisa mais registrar suas páginas com o contêiner de injeção de dependência, a menos que queira influenciar o tempo de vida da página em relação ao contêiner com os métodos AddSingleton, AddTransientou AddScoped. Para obter mais informações sobre esses métodos, consulte Duração da dependência.

Desconexão do manipulador

Ao implementar um controlo personalizado usando manipuladores, cada implementação de manipulador de plataforma deve implementar o método DisconnectHandler(), para realizar qualquer limpeza na visualização nativa, como desinscrever-se de eventos. No entanto, antes do .NET MAUI 9, a implementação DisconnectHandler() não é intencionalmente invocada pelo .NET MAUI. Em vez disso, você mesmo teria que invocá-lo ao escolher limpar um controle, como ao navegar para trás em um aplicativo.

No .NET MAUI 9, os manipuladores desconectam-se automaticamente dos seus controlos quando for possível, como ao navegar para trás numa aplicação. Em alguns cenários, talvez você não queira esse comportamento. Portanto, o .NET MAUI 9 adiciona uma propriedade anexada HandlerProperties.DisconnectPolicy para controlar quando os manipuladores são desconectados de seus controles. Esta propriedade requer um argumento HandlerDisconnectPolicy, com a enumeração definindo os seguintes valores:

  • Automatic, que indica que os manipuladores serão desconectados automaticamente. Este é o valor padrão da propriedade associada HandlerProperties.DisconnectPolicy.
  • Manual, que indica que os manipuladores terão que ser desconectados manualmente invocando a implementação DisconnectHandler().

O exemplo a seguir mostra a configuração da propriedade HandlerProperties.DisconnectPolicy anexada:

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

O código C# equivalente é:

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

Além disso, há um método de extensão DisconnectHandlers que desconecta manipuladores de um determinado IView:

video.DisconnectHandlers();

Ao desconectar, o método DisconnectHandlers se propagará pela árvore de controle até concluir ou chegar a um controle que tenha definido uma política manual.

Suporte a várias janelas

O .NET MAUI 9 adiciona a capacidade de trazer uma janela específica para a frente no Mac Catalyst e no Windows com o método Application.Current.ActivateWindow:

Application.Current?.ActivateWindow(windowToActivate);

Implantação de AOT nativa

No .NET MAUI 9, você pode optar pela implantação de AOT nativo no iOS e Mac Catalyst. A implantação nativa do AOT produz uma aplicação .NET MAUI que foi compilada antecipadamente (AOT) para código nativo. Isto produz os seguintes benefícios:

  • Tamanho reduzido do pacote do aplicativo, normalmente até 2,5 vezes menor.
  • Tempo de arranque mais rápido, normalmente até 2x mais rápido.
  • Tempo de construção mais rápido.

Para obter mais informações, consulte implantação AOT nativa no iOS e Mac Catalyst.

Incorporação nativa

O .NET MAUI 9 inclui APIs completas para cenários de incorporação nativa, que anteriormente precisavam ser adicionados manualmente ao seu projeto:

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

Como alternativa, você pode usar o método ToPlatformEmbedded, passando o Window para a plataforma na qual o aplicativo está sendo executado:

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

Em ambos os exemplos, nativeView é uma versão específica para plataformas do mauiView.

Para inicializar um aplicativo incorporado nativo no .NET MAUI 9, chame o método de extensão UseMauiEmbeddedApp em seu objeto MauiAppBuilder:

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

        builder
            .UseMauiEmbeddedApp<App>();

        return builder.Build();
    }
}

Para obter mais informações, consulte Incorporação nativa.

Modelos de projeto

O modelo de projeto .NET MAUI App inclui a capacidade de criar um aplicativo todo totalmente funcional, usando controles do Syncfusion Toolkit for .NET MAUI para visualizar dados e mantê-los em um banco de dados local baseado em SQLite. Para criar esse aplicativo todo, crie um novo projeto no Visual Studio usando o modelo de projeto .NET MAUI App e marque a caixa de seleção Incluir conteúdo de exemplo na janela Informações adicionais:

Captura de tela de como adicionar páginas de exemplo do SyncFusion ao seu projeto de aplicativo .NET MAUI.

O aplicativo todo também pode ser criado a partir da CLI do .NET com a opção --sample-content ou -sc:

dotnet new maui --sample-content -n MyProject

O .NET MAUI 9 também adiciona um modelo de projeto .NET MAUI Blazor Hybrid and Web App ao Visual Studio que cria uma solução com um aplicativo híbrido .NET MAUI Blazor e um aplicativo Blazor Web, que partilham código comum num projeto de biblioteca de classes Razor.

O modelo também pode ser usado a partir da CLI do .NET:

dotnet new maui-blazor-web -n MyProject

Dicionários de recursos

No .NET MAUI 9, um ResourceDictionary XAML autónomo (que não é suportado por um ficheiro code-behind) tem o seu XAML compilado por padrão. Para desativar esse comportamento, especifique <?xaml-comp compile="false" ?> após o cabeçalho XML.

Corte

O corte completo agora é suportado definindo a propriedade $(TrimMode) MSBuild como full. Para obter mais informações, consulte Trim a aplicação .NET MAUI.

Reduzir incompatibilidades

Os seguintes recursos do .NET MAUI são incompatíveis com o recorte completo e serão removidos pelo removedor:

Ajuste de interruptores de funcionalidades

O .NET MAUI tem diretivas de aparadores, conhecidas como opções de recursos, que tornam possível preservar o código para recursos que não são seguros para cortes. Essas diretivas de trimmer podem ser usadas quando a propriedade de compilação $(TrimMode) está definida como full, bem como para Native AOT:

Propriedade MSBuild Descrição
MauiEnableVisualAssemblyScanning Quando definido como true, o .NET MAUI verificará assemblies para tipos que implementam IVisual e para atributos [assembly:Visual(...)] e registrará esses tipos. Por padrão, essa propriedade de compilação é definida como false quando o corte completo está habilitado.
MauiShellSearchResultsRendererDisplayMemberNameSupported Quando definido como false, o valor de SearchHandler.DisplayMemberName será ignorado. Em vez disso, deve fornecer um ItemTemplate para definir a aparência do resultado SearchHandler. Por padrão, essa propriedade de compilação é definida como false quando o corte completo ou AOT nativo está habilitado.
MauiQueryPropertyAttributeSupport Quando definido como false, [QueryProperty(...)] atributos não serão usados para definir valores de propriedade durante a navegação. Em vez disso, você deve implementar a interface IQueryAttributable para aceitar parâmetros de consulta. Por padrão, essa propriedade de compilação é definida como false quando o corte completo ou AOT nativo está habilitado.
MauiImplicitCastOperatorsUsageViaReflectionSupport Quando definido como false, o .NET MAUI não procurará operadores de conversão implícitos ao converter valores de um tipo para outro. Isso pode afetar associações entre propriedades com tipos diferentes e definir um valor de propriedade de um objeto vinculável com um valor de um tipo diferente. Em vez disso, você deve definir um TypeConverter para seu tipo e anexá-lo ao tipo usando o atributo TypeConverterAttribute. Por padrão, essa propriedade de compilação é definida como false quando o corte completo ou AOT nativo está habilitado.
_MauiBindingInterceptorsSupport Quando definido como false, o .NET MAUI não intercetará nenhuma chamada para os métodos SetBinding e não tentará compilá-los. Por padrão, essa propriedade build é definida como true.
MauiEnableXamlCBindingWithSourceCompilation Quando definido como true, o .NET MAUI compilará todas as associações, incluindo aquelas em que a propriedade Source é usada. Se você habilitar esse recurso, certifique-se de que todas as associações tenham o x:DataType correto para que sejam compiladas ou limpe o tipo de dados com x:Data={x:Null}} se a associação não deva ser compilada. Por padrão, essa propriedade de compilação é definida como true quando o corte completo ou AOT nativo está habilitado.
MauiHybridWebViewSupported Quando definido como false, o controle HybridWebView não estará disponível. Por padrão, essa propriedade de compilação é definida como false quando o corte completo ou AOT nativo está habilitado.

Essas propriedades do MSBuild têm também interruptores AppContext equivalentes:

  • A propriedade MauiEnableVisualAssemblyScanning MSBuild tem uma opção AppContext equivalente chamada Microsoft.Maui.RuntimeFeature.IsIVisualAssemblyScanningEnabled.
  • A propriedade MauiShellSearchResultsRendererDisplayMemberNameSupported MSBuild tem um interruptor AppContext equivalente chamado Microsoft.Maui.RuntimeFeature.IsShellSearchResultsRendererDisplayMemberNameSupported.
  • A propriedade MauiQueryPropertyAttributeSupport MSBuild tem uma opção AppContext equivalente chamada Microsoft.Maui.RuntimeFeature.IsQueryPropertyAttributeSupported.
  • A propriedade MauiImplicitCastOperatorsUsageViaReflectionSupport MSBuild tem uma opção AppContext equivalente chamada Microsoft.Maui.RuntimeFeature.IsImplicitCastOperatorsUsageViaReflectionSupported.
  • Existe uma opção equivalente AppContext correspondente à propriedade MSBuild _MauiBindingInterceptorsSupport, chamada Microsoft.Maui.RuntimeFeature.AreBindingInterceptorsSupported.
  • A propriedade MauiEnableXamlCBindingWithSourceCompilation MSBuild tem uma opção AppContext equivalente chamada Microsoft.Maui.RuntimeFeature.MauiEnableXamlCBindingWithSourceCompilationEnabled.
  • Existe uma opção AppContext equivalente à propriedade MSBuild MauiHybridWebViewSupported chamada Microsoft.Maui.RuntimeFeature.IsHybridWebViewSupported.

A maneira mais fácil de consumir uma opção de recurso é colocando a propriedade MSBuild correspondente no arquivo de projeto do seu aplicativo (*.csproj), o que faz com que o código relacionado seja cortado dos assemblies MAUI do .NET.

Implantação de aplicativos do Windows

Ao depurar e implantar um novo projeto .NET MAUI no Windows, o comportamento padrão no .NET MAUI 9 é implantar um aplicativo não empacotado. Para obter mais informações, consulte Implantar e depurar seu aplicativo .NET MAUI no Windows.

Códigos de erro do compilador XAML

No .NET MAUI 9, os códigos de erro do compilador XAML alteraram seu prefixo de XFC para XC. Certifique-se de atualizar as propriedades de compilação $(WarningsAsErrors), $(WarningsNotAsErrors)e $(NoWarn) nos arquivos de projeto do seu aplicativo, se usados, para fazer referência ao novo prefixo.

Extensões de marcação XAML

Todas as classes que implementam IMarkupExtension, IMarkupExtension<T>, IValueProvidere IExtendedTypeConverter precisam ser anotadas com o RequireServiceAttribute ou AcceptEmptyServiceProviderAttribute. Isso é necessário devido a uma otimização de compilador XAML introduzida no .NET MAUI 9 que permite a geração de código mais eficiente, o que ajuda a reduzir o tamanho do aplicativo e melhorar o desempenho do tempo de execução.

Para obter informações sobre como anotar extensões de marcação com esses atributos, consulte Service providers.

Sincronização Xcode

O .NET MAUI 9 inclui o Xcode sync (xcsync), que é uma ferramenta que permite usar o Xcode para gerenciar arquivos específicos da Apple com projetos .NET, incluindo catálogos de ativos, arquivos plist, storyboards e arquivos xib. A ferramenta tem dois comandos principais para gerar um projeto Xcode temporário a partir de um projeto .NET e para sincronizar as alterações dos arquivos Xcode de volta para o seu projeto .NET.

Use dotnet build com os comandos xcsync-generate ou xcsync-sync para gerar ou sincronizar esses arquivos e passar um arquivo de projeto e argumentos adicionais:

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

Para obter mais informações, consulte Xcode Sync.

APIs obsoletas

O .NET MAUI 9 substitui algumas APIs, que serão completamente removidas em uma versão futura.

Moldura

O controle Frame está marcado como obsoleto no .NET MAUI 9 e será completamente removido em uma versão futura. O controlo Border deve ser usado no seu lugar.

Ao substituir um Frame por um Border, o valor da propriedade Frame.BorderColor deve se tornar o valor da propriedade Border.Stroke e o valor da propriedade Frame.CornerRadius deve se tornar parte do valor da propriedade Border.StrokeShape. Além disso, pode ser necessário duplicar o valor Margin como o valor Padding.

O exemplo a seguir mostra elementos Frame e Border equivalentes em XAML:

<Frame BorderColor="DarkGray"
       CornerRadius="5"
       Margin="20"
       HeightRequest="360"
       HorizontalOptions="Center"
       VerticalOptions="Center" />

<Border Stroke="DarkGray"
        StrokeShape="RoundRectangle 5"
        Margin="20"
        Padding="20"
        HeightRequest="360"
        HorizontalOptions="Center"
        VerticalOptions="Center" />

Para obter mais informações, consulte a secção Fronteira.

Página Principal

Em vez de definir a primeira página do seu aplicativo usando a propriedade MainPage em um objeto Application, você deve definir a propriedade Page em um Window para a primeira página do seu aplicativo. Isso é o que acontece internamente no .NET MAUI quando você define a propriedade MainPage, portanto, não há nenhuma alteração de comportamento introduzida pela propriedade MainPage sendo marcada como obsoleta.

O exemplo a seguir mostra a configuração da propriedade Page em um Window, por meio da substituição de CreateWindow:

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

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

O código que acessa a propriedade Application.Current.MainPage agora deve acessar a propriedade Application.Current.Windows[0].Page para aplicativos com uma única janela. Para aplicativos com várias janelas, use a coleção Application.Current.Windows para identificar a janela correta e acessar a propriedade Page. Além disso, cada elemento apresenta uma propriedade Window, que é acessível quando o elemento faz parte da janela atual, a partir da qual a propriedade Page pode ser acessada (Window.Page). O código da plataforma pode recuperar o objeto IWindow do aplicativo com o método de extensão Microsoft.Maui.Platform.GetWindow.

Embora a propriedade MainPage seja mantida no .NET MAUI 9, ela será completamente removida em uma versão futura.

Layouts de compatibilidade

As classes de layout de compatibilidade no namespace Microsoft.Maui.Controls.Compatibility foram obsoletas.

Chamadas de sistemas herdados

Os seguintes métodos de medição VisualElement tornaram-se obsoletos:

Esses são métodos de medição herdados que não funcionam corretamente com as expectativas de layout do .NET MAUI.

Em substituição, foi introduzido o método VisualElement.Measure(Double, Double). Esse método retorna o tamanho mínimo que um elemento precisa para ser exibido em um dispositivo. As margens são excluídas da medição, mas são retornadas com o tamanho. Este é o método preferido a utilizar quando se mede uma vista.

Além disso, a estrutura SizeRequest está obsoleta. Em vez disso, Size deve ser usado.

Atualização do .NET 8 para o .NET 9

Para atualizar seus projetos .NET MAUI do .NET 8 para o .NET 9, primeiro instale o .NET 9 e a carga de trabalho do .NET MAUI com Visual Studio 17.12+ou com Visual Studio Code e a extensão .NET MAUI e as cargas de trabalho .NET e .NET MAUI, ou com o do instalador autônomo e o comando .

Atualizar arquivo de projeto

Para atualizar seu aplicativo .NET MAUI do .NET 8 para o .NET 9, abra o arquivo de projeto do aplicativo (.csproj) e altere o Target Framework Monikers (TFMs) de 8 para 9. Se você estiver usando um TFM como net8.0-ios15.2 certifique-se de corresponder à versão da plataforma ou removê-la completamente. O exemplo a seguir mostra os TFMs para um projeto .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>

O exemplo a seguir mostra os TFMs para um projeto .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 o arquivo de projeto do seu aplicativo fizer referência a uma versão .NET 8 do pacote NuGet do Microsoft.Maui.Controls, diretamente ou por meio da propriedade $(MauiVersion) build, atualize isso para uma versão do .NET 9. Em seguida, remova a referência de pacote para o pacote NuGet Microsoft.Maui.Controls.Compatibility, desde que seu aplicativo não use nenhum tipo desse pacote. Além disso, atualize a referência de pacote para o pacote NuGet Microsoft.Extensions.Logging.Debug para a versão mais recente do .NET 9.

Se o seu aplicativo tiver como alvo iOS ou Mac Catalyst, atualize as propriedades de compilação $(SupportedOSPlatformVersion) para essas plataformas para 15.0:

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

Ao depurar e implantar um novo projeto .NET MAUI no Windows, o comportamento padrão no .NET 9 é implantar um aplicativo não empacotado. Para adotar este comportamento, consulte Converter uma aplicação .NET MAUI Windows empacotada para desempacotada.

Antes de criar seu aplicativo atualizado pela primeira vez, exclua as pastas bin e obj. Quaisquer erros de compilação e avisos irão guiá-lo para as próximas etapas.

Atualizar códigos de erro do compilador XAML

Os códigos de erro do compilador XAML alteraram seu prefixo de XFC para XC, portanto, atualize as propriedades de compilação $(WarningsAsErrors), $(WarningsNotAsErrors)e $(NoWarn) no arquivo de projeto do seu aplicativo, se usado, para fazer referência ao novo prefixo.

Endereçar novos avisos de compilador XAML para associações compiladas

Avisos de construção serão produzidos para ligações que não utilizam associações compiladas, e será necessário resolvê-los. Para obter mais informações, consulte avisos de associações compiladas XAML.

Atualizar extensões de marcação XAML

As extensões de marcação XAML precisarão ser anotadas com o RequireServiceAttribute ou AcceptEmptyServiceProviderAttribute. Isso é necessário devido a uma otimização de compilador XAML que permite a geração de código mais eficiente, o que ajuda a reduzir o tamanho do aplicativo e melhorar o desempenho do tempo de execução. Para obter mais informações, consulte Provedores de serviços.

Endereçar APIs preteridas

O .NET MAUI 9 substitui algumas APIs, que serão completamente removidas em uma versão futura. Portanto, resolva todos os avisos de compilação sobre APIs obsoletas. Para obter mais informações, consulte APIs preteridas.

Adotar associações compiladas que definem a propriedade Source

Você pode optar por compilar associações que definem a propriedade Source, para aproveitar um melhor desempenho de tempo de execução. Para obter mais informações, consulte Compilar associações que definem a propriedade Source.

Adotar ligações compiladas em C#

Você pode optar por compilar expressões de vinculação que são declaradas no código, para aproveitar o melhor desempenho do tempo de execução. Para obter mais informações, veja Associações compiladas no código.

Adote o corte total

Você pode adotar o uso de corte completo, para reduzir o tamanho geral do seu aplicativo, definindo a propriedade $(TrimMode) MSBuild como full. Para obter mais informações, consulte Optimizar uma aplicação .NET MAUI.

Adote a implantação do NativeAOT em plataformas suportadas

Você pode optar pela implantação do AOT nativo no iOS e Mac Catalyst. A implementação nativa do AOT produz uma aplicação .NET MAUI que foi compilada antecipadamente para código nativo. Para obter mais informações, consulte implantação AOT nativa no iOS e Mac Catalyst.

.NET para Android

Na versão .NET 9, o .NET para Android adiciona suporte à API 35, inclui esforços para reduzir os tempos de compilação e aumentar a capacidade de otimização das aplicações, visando reduzir o tamanho e melhorar o desempenho. Para obter mais informações sobre o .NET para Android no .NET 9, consulte as seguintes notas de versão:

Pacotes de ativos

O .NET para Android no .NET 9 introduz a capacidade de colocar ativos em um pacote separado, conhecido como asset pack. Isso permite que você carregue jogos e aplicativos que normalmente seriam maiores do que o tamanho básico do pacote permitido pelo Google Play. Ao colocar esses ativos em um pacote separado, você ganha a capacidade de carregar um pacote que tem até 2Gb de tamanho, em vez do tamanho básico do pacote de 200Mb.

Importante

Os pacotes de ativos só podem conter ativos. No caso do .NET para Android, isso significa itens que têm a ação de compilação AndroidAsset.

Os aplicativos .NET MAUI definem ativos através da ação de compilação MauiAsset. Um pacote de ativos pode ser especificado por meio do atributo AssetPack:

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

Observação

Os metadados adicionais serão ignorados por outras plataformas.

Se você tiver itens específicos que deseja colocar em um pacote de ativos, poderá usar o atributo Update para definir os metadados AssetPack:

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

Os pacotes de ativos podem ter diferentes opções de entrega, que controlam quando seus ativos serão instalados no dispositivo:

  • Os pacotes de tempo de instalação são instalados simultaneamente com a aplicação. Este tipo de pacote pode ter até 1Gb de tamanho, mas você só pode ter um deles. Este tipo de entrega é especificado com os metadados InstallTime.
  • Os pacotes de seguimento rápido serão instalados em algum momento logo após a conclusão da instalação do aplicativo. O aplicativo será capaz de iniciar enquanto este tipo de pacote está sendo instalado, então você deve verificar se ele terminou de instalar antes de tentar usar os ativos. Este tipo de pacote de ativos pode ter até 512Mb de tamanho. Este tipo de entrega é especificado nos metadados FastFollow.
  • Os pacotes sob demanda nunca serão baixados para o dispositivo, a menos que o aplicativo solicite especificamente. O tamanho total de todos os seus pacotes de ativos não pode exceder 2 Gb e você pode ter até 50 pacotes de ativos separados. Esse tipo de entrega é especificado com metadados designados como OnDemand.

Em aplicativos .NET MAUI, o tipo de entrega pode ser especificado com o atributo DeliveryType em um MauiAsset:

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

Para obter mais informações sobre pacotes de ativos Android, consulte pacotes de ativos Android.

Suporte para Android 15

O .NET para Android no .NET 9 adiciona ligações .NET para Android 15 (API 35). Para criar para essas APIs, atualize a estrutura de destino do seu projeto para net9.0-android:

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

Observação

Você também pode especificar net9.0-android35 como uma estrutura de destino, mas o número 35 provavelmente mudará em versões futuras do .NET para corresponder às versões mais recentes do sistema operacional Android.

Arquiteturas de 64 bits por padrão

O .NET para Android no .NET 9 não cria mais os seguintes identificadores de tempo de execução (RIDs) por padrão:

  • android-arm
  • android-x86

Isso deve melhorar os tempos de compilação e reduzir o tamanho dos arquivos .apk Android. Observe que o Google Play é compatível com a divisão de pacotes de aplicativos por arquitetura.

Se você precisar criar para essas arquiteturas, você pode adicioná-las ao seu arquivo de projeto (.csproj):

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

Ou num projeto com vários objetivos:

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

Métodos de marechal Android

Melhorias nos métodos de marshal do Android no .NET 9 fizeram com que o recurso funcionasse de forma mais confiável em aplicativos, mas ainda não é o padrão. Habilitar este recurso resultou em uma melhoria de ~10% no desempenho em uma aplicação de teste.

Os métodos de marshal Android podem ser ativados no seu arquivo de projeto (.csproj) através da propriedade $(AndroidEnableMarshalMethods):

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

Para obter detalhes específicos sobre o recurso, consulte a documentação do recurso ou de implementação no GitHub.

Aprimoramentos de corte

No .NET 9, os assemblies da API do Android (Mono.Android.dll, Java.Interop.dll) são agora totalmente compatíveis com trim. Para optar pelo corte completo, defina a propriedade $(TrimMode) no arquivo de projeto (.csproj):

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

Isso também permite cortar analisadores, para que avisos sejam introduzidos para qualquer código C# problemático.

Para obter mais informações, consulte Reduzindo a granularidade.

.NET para iOS

O .NET 9 no iOS, tvOS, Mac Catalyst e macOS usa o Xcode 16.0 para as seguintes versões de plataforma:

  • iOS: 18.0
  • tvOS: 18,0
  • Mac Catalyst: 18.0
  • macOS: 15.0

Para obter mais informações sobre o .NET 9 no iOS, tvOS, Mac Catalyst e macOS, consulte as seguintes notas de versão:

Ligações

O .NET para iOS 9 introduz a capacidade de direcionar múltiplas versões do .NET para integrações com o iOS. Por exemplo, um projeto de biblioteca pode precisar criar para duas versões distintas do iOS:

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

Isso produzirá duas bibliotecas, uma usando ligações do iOS 17.0 e outra usando ligações do iOS 17.2.

Importante

Um projeto de aplicativo deve sempre ter como alvo o SDK do iOS mais recente.

Aprimoramentos de corte

Com o .NET 9, as assemblages iOS e Mac Catalyst (Microsoft.iOS.dll, Microsoft.MacCatalyst.dll etc.) são agora totalmente compatíveis com a funcionalidade de 'trim'. Para optar pelo corte completo, defina a propriedade $(TrimMode) no arquivo de projeto (.csproj):

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

Isso também permite cortar analisadores, para que avisos sejam introduzidos para qualquer código C# problemático.

Para obter mais informações, consulte Reduzindo a granularidade.

AOT nativo para iOS & Mac Catalyst

No .NET para iOS 9, a compilação nativa Ahead of Time (AOT) para iOS e Mac Catalyst utiliza a otimização completa para reduzir o tamanho do pacote e melhorar o desempenho de inicialização da sua aplicação. O NativeAOT baseia-se no corte completo, optando também por um novo tempo de execução.

Importante

A tua aplicação e as suas dependências devem estar prontas para otimização para utilizar esta funcionalidade.

O NativeAOT requer que os aplicativos sejam criados sem avisos de trimmer, para garantir que o aplicativo funcione corretamente em tempo de execução.

Ver também