Поделиться через


Новые возможности .NET MAUI для .NET 9

Основное внимание в пользовательском интерфейсе приложений .NET Multi-platform (.NET MAUI) в .NET 9 уделяется улучшению качества продукта. Это включает расширение охвата тестов, завершение тестирования сценариев и исправление ошибок. Дополнительные сведения о улучшении качества продукта в .NET MAUI 9 см. в следующих заметках о выпуске:

Внимание

Из-за работы с внешними зависимостями, такими как средства Xcode или Android SDK, политика поддержки .NET MAUI отличается от политики поддержки .NET и .NET Core. Дополнительные сведения см. в политике поддержки .NET MAUI.

Совместимость с Xcode 16, которая включает поддержку пакета SDK для iOS 18, iPadOS 18, tvOS 18 и macOS 15, требуется при сборке с помощью .NET MAUI 9. Для Xcode 16 требуется macOS 14.5 или более поздней версии.

В .NET 9 MAUI .NET поставляется в виде рабочей нагрузки .NET и нескольких пакетов NuGet. Преимущество этого подхода заключается в том, что он позволяет легко закреплять проекты в определенных версиях, а также позволяет легко просматривать нераспроданные или экспериментальные сборки. При создании проекта .NET MAUI необходимые пакеты NuGet автоматически добавляются в проект.

Минимальные целевые объекты развертывания

Для .NET MAUI 9 требуются минимальные целевые объекты развертывания iOS 12.2 и Mac Catalyst 15.0 (macOS 12.0). Целевые показатели минимального развертывания Android и Windows остаются неизменными. Дополнительные сведения см. в разделе "Поддерживаемые платформы для приложений .NET MAUI".

Новые элементы управления

.NET MAUI 9 включает два новых элемента управления.

HybridWebView

HybridWebView включает размещение произвольного содержимого HTML/JS/CSS в веб-представлении и обеспечивает обмен данными между кодом в веб-представлении (JavaScript) и кодом, на котором размещено веб-представление (C#/.NET). Например, если у вас есть существующее приложение React JS, его можно разместить в кроссплатформенной машинном приложении .NET MAUI и создать серверную часть приложения с помощью C# и .NET.

Чтобы создать приложение .NET MAUI, HybridWebView необходимо:

  • Веб-содержимое приложения, состоящее из статического HTML, JavaScript, CSS, изображений и других файлов.
  • Элемент HybridWebView управления в составе пользовательского интерфейса приложения. Это можно сделать, ссылаясь на него в XAML приложения.
  • Код в веб-содержимом и в C#/.NET, который использует HybridWebView API для отправки сообщений между двумя компонентами.

Все приложение, включая веб-содержимое, упаковано и выполняется локально на устройстве и может быть опубликовано в применимых магазинах приложений. Веб-содержимое размещается в собственном элементе управления веб-представления и выполняется в контексте приложения. Любая часть приложения может получить доступ к внешним веб-службам, но не требуется.

Дополнительные сведения см. в разделе HybridWebView.

Заголовок панели для Windows

Элемент TitleBar управления предоставляет возможность добавить настраиваемую строку заголовка в приложение в Windows:

Обзор панели заголовков .NET MAUI.

Можно TitleBar задать как значение свойства в любом Window.TitleBarиз следующих значений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>

Пример его использования в C#:

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

A TitleBar очень настраивается с помощью его Contentсвойств LeadingContentи 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>

На следующем снимок экрана показан полученный внешний вид:

Снимок экрана панели заголовка .NET MAUI.

Примечание.

Поддержка Mac Catalyst для TitleBar элемента управления будет добавлена в будущий выпуск.

Дополнительные сведения см. в разделе TitleBar.

Усовершенствования элементов управления

.NET MAUI 9 включает усовершенствования элементов управления.

Режим привязки BackButtonBehavior OneWay

Теперь вместо режима привязки для IsVisible приложения оболочки и IsEnabledBackButtonBehavior в приложении BindingMode.OneWay оболочки BindingMode.OneTime. Это позволяет более легко управлять поведением кнопки "Назад" во время выполнения с привязками данных:

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

BlazorWebView

Умолчательное поведение для размещения содержимого в BlazorWebView изменилось на 0.0.0.1. Внутренний 0.0.0.0 адрес, используемый для размещения содержимого, больше не работает и приводит к тому, BlazorWebView что не загружается содержимое и отрисовка в виде пустого прямоугольника.

Чтобы воспользоваться адресом 0.0.0.0 , добавьте следующий код в CreateMauiApp метод в 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);

По умолчанию BlazorWebView теперь активирует и забывает асинхронное удаление базового WebViewManager. Это снижает вероятность возникновения взаимоблокировок удаления в Android.

Предупреждение

Это поведение по умолчанию означает, что удаление может вернуться до удаления всех объектов, что может привести к изменению поведения в приложении. Элементы, которые удаляются, частично являются собственными внутренними типами Blazor, но и определяемыми приложением типами, такими как службы с областью действия, используемые в BlazorWebView пределах части приложения.

Чтобы отказаться от этого поведения, необходимо настроить приложение для блокировки удаления с помощью коммутатора AppContext в методе CreateMauiApp в классе MauiProgram :

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

Если приложение настроено на блокировку удаления с помощью этого коммутатора, BlazorWebView выполняет асинхронное удаление синхронизации, то есть блокирует поток до завершения асинхронного удаления. Однако это может привести к взаимоблокировкам, если удаление должно выполнять код в одном потоке (так как поток заблокирован во время ожидания).

Кнопки в iOS

Button Элементы управления в iOS теперь учитывают интервалы, заполнение, ширину границы и поля более точно, чем в предыдущих выпусках. Теперь большое изображение будет Button изменено на максимальный размер, учитывая интервалы, заполнение, ширину границы и поля. Тем не менее, если Button содержит текст и изображение, возможно, не удается поместить все содержимое внутри кнопки, и поэтому необходимо вручную размер изображения, чтобы достичь требуемого макета.

CollectionView и CarouselView

.NET MAUI 9 включает два необязательных новых обработчика в iOS и Mac Catalyst, которые позволяют повысить CollectionViewCarouselViewпроизводительность и стабильность. Эти обработчики основаны на UICollectionView API.

Чтобы воспользоваться этими обработчиками, добавьте следующий код в 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

ContentPage

В .NET MAUI 9 HideSoftInputOnTapped свойство также поддерживается в Mac Catalyst, а также в Android и iOS.

Поддержка ввода обратимой клавиатуры

.NET MAUI 9 добавляет новую поддержку ввода обратимой клавиатуры для Password, Dateи Time. Их можно включить Editor и Entry элементы управления:

<Entry Keyboard="Date" />

Text alignment

Перечисление TextAlignment добавляет Justify элемент, который можно использовать для выравнивания текста в текстовых элементах управления. Например, можно горизонтально выровнять текст в LabelHorizontalTextAlignment.Justifyвиде :

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

TimePicker

TimePicker TimeSelected получает событие, которое возникает при изменении выбранного времени. Объект TimeChangedEventArgs , сопровождающий TimeSelected событие, имеет NewTime и OldTime свойства, которые указывают новое и старое время соответственно.

WebView

WebView ProcessTerminated добавляет событие, которое возникает при неожиданном WebView завершении процесса. Объект WebViewProcessTerminatedEventArgs , сопровождающий это событие, определяет свойства конкретной платформы, указывающие, почему процесс завершился сбоем.

Скомпилированные привязки в коде

Привязки, написанные в коде, обычно используют строковые пути, которые разрешаются во время выполнения с отражением, а затраты на это зависят от платформы до платформы. В .NET MAUI 9 представлен дополнительный SetBinding метод расширения, который определяет привязки с помощью Func аргумента вместо строкового пути:

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

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

Этот скомпилированный подход привязки обеспечивает следующие преимущества:

  • Улучшена производительность привязки данных путем разрешения выражений привязки во время компиляции, а не во время выполнения.
  • Лучший интерфейс устранения неполадок разработчика, так как недопустимые привязки сообщаются как ошибки сборки.
  • Intellisense во время редактирования.

Не все методы можно использовать для определения скомпилированной привязки. Выражение должно быть простым выражением доступа к свойствам. В следующих примерах показаны допустимые и недопустимые выражения привязки:

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

Предупреждение

Ошибка компилятора CS0272 возникнет, если аксессор set для свойства или индексатора недоступен. Если это происходит, увеличьте доступность аксессора.

Кроме того, .NET MAUI 9 добавляет BindingBase.Create метод, который задает привязку непосредственно к объекту с Funcпомощью объекта и возвращает экземпляр объекта привязки:

// 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()
});

Внимание

Скомпилированные привязки требуются вместо строковых привязок в приложениях NativeAOT и в приложениях с поддержкой полной обрезки.

Дополнительные сведения о скомпилированных привязках в коде см. в разделе «Скомпилированные привязки в коде».

Скомпилированные привязки в XAML

В .NET MAUI 8 скомпилированные привязки отключены для любых выражений привязки XAML, определяющих Source свойство, и не поддерживаются в нескольких привязках. Эти ограничения были удалены в .NET MAUI 9. Сведения о компиляции выражений привязки XAML, определяющих Source свойство, см. в разделе "Компиляция привязок", определяющих Source свойство.

По умолчанию .NET MAUI 9 создает предупреждения сборки для привязок, которые не используют скомпилированные привязки. Дополнительные сведения о предупреждениях компилированных привязок XAML см . в предупреждениях скомпилированных привязок XAML.

Внедрение зависимостей

В приложении Оболочки больше не нужно регистрировать страницы с контейнером внедрения зависимостей, если вы не хотите влиять на время существования страницы относительно контейнера с AddSingletonAddTransientпомощью методов или AddScoped методов. Дополнительные сведения об этих методах см. в разделе о времени существования зависимостей.

Отключение обработчика

При реализации пользовательского элемента управления с помощью обработчиков каждой реализации обработчика платформы требуется для реализации метода для выполнения любой очистки собственного DisconnectHandler() представления, например отмены подписки на события. Однако до .NET MAUI 9 DisconnectHandler() реализация намеренно не вызывается .NET MAUI. Вместо этого вам придется вызывать его самостоятельно при выборе очистки элемента управления, например при переходе назад в приложении.

В .NET MAUI 9 обработчики автоматически отключают от своих элементов управления, например при переходе назад в приложении. В некоторых сценариях это поведение может не потребоваться. Поэтому .NET MAUI 9 добавляет присоединенное HandlerProperties.DisconnectPolicy свойство для управления при отключении обработчиков от их элементов управления. Для этого свойства требуется HandlerDisconnectPolicy аргумент с перечислением, определяющим следующие значения:

  • Automatic, указывающее, что обработчики будут отключены автоматически. Это значение по умолчанию для присоединенного свойства HandlerProperties.DisconnectPolicy.
  • Manual, указывающее, что обработчики должны быть отключены вручную путем вызова DisconnectHandler() реализации.

В следующем примере показано задание присоединенного HandlerProperties.DisconnectPolicy свойства:

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

Эквивалентный код на C# выглядит так:

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

Кроме того, существует DisconnectHandlers метод расширения, который отключает обработчики от заданного:IView

video.DisconnectHandlers();

При отключении метод будет распространяться по дереву управления до тех пор, DisconnectHandlers пока он не завершится или не появится в элементе управления, настроив политику вручную.

Поддержка нескольких окон

.NET MAUI 9 добавляет возможность перенести определенное окно на передний план в Mac Catalyst и Windows с Application.Current.ActivateWindow помощью метода:

Application.Current?.ActivateWindow(windowToActivate);

Развертывание AOT в собственном коде

В .NET MAUI 9 вы можете выбрать собственное развертывание AOT в iOS и Mac Catalyst. В собственном развертывании AOT создается приложение .NET MAUI, скомпилированное в машинный код. Это дает следующие преимущества:

  • Уменьшен размер пакета приложения, как правило, до 2,5x меньше.
  • Более быстрое время запуска, как правило, до 2x быстрее.
  • Быстрее времени сборки.

Дополнительные сведения см. в статье о развертывании Native AOT в iOS и Mac Catalyst.

Встроенное внедрение

.NET MAUI 9 включает полные API для собственных сценариев внедрения, которые ранее пришлось вручную добавить в проект:

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

Кроме того, можно использовать ToPlatformEmbedded метод, передавая Window платформу, на которой выполняется приложение:

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

В обоих примерах — это версия nativeViewдля конкретной платформыmauiView.

Чтобы загрузить собственное внедренное приложение в .NET MAUI 9, вызовите метод расширения в объекте UseMauiEmbeddedAppMauiAppBuilder :

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

        builder
            .UseMauiEmbeddedApp<App>();

        return builder.Build();
    }
}

Дополнительные сведения см. в разделе "Внедрение машинного кода".

Шаблоны проектов

Шаблон проекта приложения .NET MAUI включает возможность создания полнофункциональное приложение todo, используя элементы управления из набора средств Syncfusion для .NET MAUI для визуализации данных и сохранения их в локальной базе данных на основе SQLite. Чтобы создать это приложение todo, создайте проект в Visual Studio с помощью шаблона проекта приложения .NET MAUI, а затем установите флажок "Включить пример содержимого " в окне "Дополнительные сведения ":

Снимок экрана: добавление примеров страниц SyncFusion в проект приложения .NET MAUI.

Приложение todo также можно создать из интерфейса командной строки .NET с --sample-content помощью или -sc параметра:

dotnet new maui --sample-content -n MyProject

.NET MAUI 9 также добавляет шаблон проекта .NET MAUI Blazor Hybrid и Web App в Visual Studio, который создает решение с гибридным приложением .NET MAUI Blazor с приложением Blazor Web, которое предоставляет общий код в проекте библиотеки классов Razor.

Шаблон также можно использовать из интерфейса командной строки .NET:

dotnet new maui-blazor-web -n MyProject

Словари ресурсов

В .NET MAUI 9 автономный XAML ResourceDictionary (который не поддерживается файлом программной части) по умолчанию компилируется в XAML. Чтобы отказаться от этого поведения, укажите <?xaml-comp compile="false" ?> после заголовка XML.

Отделка

Полная обрезка теперь поддерживается, задав $(TrimMode) для свойства MSBuild значение full. Дополнительные сведения см. в разделе Обрезать приложение .NET MAUI.

Обрезка несовместимости

Следующие функции .NET MAUI несовместимы с полной обрезкой и будут удалены триммером:

Обрезка переключателей функций

В .NET MAUI есть директивы триммера, известные как коммутаторы функций, которые позволяют сохранить код для функций, которые не являются безопасными. Эти директивы триммера можно использовать, если $(TrimMode) для свойства сборки задано значение full, а также для собственного AOT:

Свойство MSBuild Description
MauiEnableVisualAssemblyScanning Если задано значение true, .NET MAUI сканирует сборки для типов, реализующих IVisual и для [assembly:Visual(...)] атрибутов, и будет регистрировать эти типы. По умолчанию это свойство сборки имеет false значение, если включена полная обрезка.
MauiShellSearchResultsRendererDisplayMemberNameSupported Если задано значение false, значение SearchHandler.DisplayMemberName будет игнорироваться. Вместо этого необходимо указать внешний ItemTemplateSearchHandler вид результатов. По умолчанию это свойство сборки имеет false значение, если включена полная обрезка или собственный AOT.
MauiQueryPropertyAttributeSupport Если задано значение false, [QueryProperty(...)] атрибуты не будут использоваться для задания значений свойств при переходе. Вместо этого следует реализовать IQueryAttributable интерфейс для принятия параметров запроса. По умолчанию это свойство сборки имеет false значение, если включена полная обрезка или собственный AOT.
MauiImplicitCastOperatorsUsageViaReflectionSupport Если задано значение false, .NET MAUI не будет искать неявные операторы преобразования при преобразовании значений из одного типа в другой. Это может повлиять на привязки между свойствами с разными типами и задать значение свойства привязываемого объекта со значением другого типа. Вместо этого необходимо определить TypeConverter тип и присоединить его к типу с помощью атрибута TypeConverterAttribute . По умолчанию это свойство сборки имеет false значение, если включена полная обрезка или собственный AOT.
_MauiBindingInterceptorsSupport Если задано значение false, .NET MAUI не перехватывает вызовы SetBinding методов и не пытается компилировать их. По умолчанию для этого свойства сборки задано trueзначение .
MauiEnableXamlCBindingWithSourceCompilation Если задано значение true, .NET MAUI компилирует все привязки, включая те, где Source используется свойство. Если включить эту функцию, убедитесь, что все привязки имеют правильную версию x:DataType , чтобы они компилировались, или очистить тип данных, если x:Data={x:Null}} привязка не должна быть скомпилирована. По умолчанию это свойство сборки имеет true значение, если включена полная обрезка или собственный AOT.
MauiHybridWebViewSupported Если задано значение false, HybridWebView элемент управления не будет доступен. По умолчанию это свойство сборки имеет false значение, если включена полная обрезка или собственный AOT.

Эти свойства MSBuild также имеют эквивалентные AppContext коммутаторы:

  • Свойство MauiEnableVisualAssemblyScanning MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.IsIVisualAssemblyScanningEnabled.
  • Свойство MauiShellSearchResultsRendererDisplayMemberNameSupported MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.IsShellSearchResultsRendererDisplayMemberNameSupported.
  • Свойство MauiQueryPropertyAttributeSupport MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.IsQueryPropertyAttributeSupported.
  • Свойство MauiImplicitCastOperatorsUsageViaReflectionSupport MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.IsImplicitCastOperatorsUsageViaReflectionSupported.
  • Свойство _MauiBindingInterceptorsSupport MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.AreBindingInterceptorsSupported.
  • Свойство MauiEnableXamlCBindingWithSourceCompilation MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.MauiEnableXamlCBindingWithSourceCompilationEnabled.
  • Свойство MauiHybridWebViewSupported MSBuild имеет эквивалентный AppContext параметр с именем Microsoft.Maui.RuntimeFeature.IsHybridWebViewSupported.

Самый простой способ использовать переключатель функций — поместить соответствующее свойство MSBuild в файл проекта приложения (*.csproj), что приводит к обрезке связанного кода из сборок .NET MAUI.

Развертывание приложений Windows

При отладке и развертывании нового проекта MAUI .NET в Windows поведение по умолчанию в .NET MAUI 9 заключается в развертывании распаковки приложения. Дополнительные сведения см. в статье "Развертывание и отладка приложения .NET MAUI в Windows".

Коды ошибок компилятора XAML

В .NET MAUI 9 коды ошибок компилятора XAML изменили свой префикс с XFCXC. Убедитесь, что вы обновляете $(WarningsAsErrors)$(WarningsNotAsErrors)свойства и $(NoWarn) создаете свойства в файлах проекта приложения, если используется, чтобы ссылаться на новый префикс.

Расширения разметки XAML

Все классы, реализующие , IMarkupExtensionи должны быть аннотированы с помощью или IMarkupExtension<T>IValueProvider.IExtendedTypeConverterRequireServiceAttributeAcceptEmptyServiceProviderAttribute Это необходимо из-за оптимизации компилятора XAML, введенной в .NET MAUI 9, которая позволяет создавать более эффективный код, что помогает уменьшить размер приложения и повысить производительность среды выполнения.

Сведения об аннотации расширений разметки с этими атрибутами см. в разделе "Поставщики служб".

Синхронизация Xcode

.NET MAUI 9 включает синхронизацию Xcode (xcsync), которая позволяет использовать Xcode для управления конкретными файлами Apple с проектами .NET, включая каталоги активов, plist-файлы, раскадровки и XIB-файлы. Средство содержит две основные команды для создания временного проекта Xcode из проекта .NET и синхронизации изменений из файлов Xcode обратно в проект .NET.

Вы используете dotnet build для xcsync-generatexcsync-sync создания или синхронизации этих файлов и передачи в файл проекта и дополнительных аргументов:

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

Дополнительные сведения см. в разделе синхронизации Xcode.

Устаревшие интерфейсы API

.NET MAUI 9 не рекомендует некоторые API, которые будут полностью удалены в будущем выпуске.

Кадр

Элемент Frame управления помечен как устаревший в .NET MAUI 9 и будет полностью удален в будущем выпуске. Элемент Border управления должен использоваться на его месте.

При замене Frame на Borderзначение свойства Frame.BorderColor должно стать значением свойства Border.Stroke, а значение свойства Frame.CornerRadius должно стать частью значения свойства Border.StrokeShape. Кроме того, может потребоваться дублировать значение Margin в качестве значения Padding.

В следующем примере показаны эквивалентные элементы Frame и Border в 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" />

Дополнительные сведения см. в разделе Border.

MainPage

Вместо определения первой страницы приложения с помощью MainPage свойства в Application объекте необходимо задать Page свойство на Window первой странице приложения. Это то, что происходит внутри .NET MAUI при установке MainPage свойства, поэтому изменение поведения, введенное MainPage свойством, помеченным как устаревшее.

В следующем примере показано задание Page свойства на объекте WindowCreateWindow с помощью переопределения:

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

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

Код, который обращается к Application.Current.MainPage свойству, теперь должен получить доступ к свойству Application.Current.Windows[0].Page для приложений с одним окном. Для приложений с несколькими окнами используйте Application.Current.Windows коллекцию, чтобы определить правильное окно, а затем получить доступ к свойству Page . Кроме того, каждый элемент имеет Window свойство, которое доступно, когда элемент является частью текущего окна, из которого Page можно получить доступ к свойству (Window.Page). Код платформы может получить объект приложения IWindow с Microsoft.Maui.Platform.GetWindow помощью метода расширения.

MainPage Хотя свойство сохраняется в .NET MAUI 9, оно будет полностью удалено в будущем выпуске.

Макеты совместимости

Классы макета совместимости в Microsoft.Maui.Controls.Compatibility пространстве имен устарели.

Вызовы устаревших мер

VisualElement Следующие методы мер устарели:

Это устаревшие методы мер, которые неправильно работают с ожиданиями макета .NET MAUI.

В VisualElement.Measure(Double, Double) качестве замены был введен метод. Этот метод возвращает минимальный размер, необходимый элементу для отображения на устройстве. Поля исключаются из измерения, но возвращаются с размером. Это предпочтительный метод для вызова при измерении представления.

Кроме того, структуру SizeRequest устарела. Вместо этого Size следует использовать.

Обновление с .NET 8 до .NET 9

Чтобы обновить проекты .NET MAUI с .NET 8 до .NET 9, сначала установите .NET 9 и рабочую нагрузку .NET MAUI с Visual Studio 17.12+ или с расширением .NET MAUI и .NET и рабочими нагрузками .NET MAUI или с автономным установщиком и dotnet workload install maui командой.

Обновление файла проекта

Чтобы обновить приложение .NET MAUI от .NET 8 до .NET 9, откройте файл проекта приложения (CSPROJ) и измените monikers Target Framework (TFMs) с 8 до 9. Если вы используете TFM, например net8.0-ios15.2 обязательно соответствуете версии платформы или полностью удалите ее. В следующем примере показаны TFMs для проекта .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>

В следующем примере показаны TFMs для проекта .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>

Если файл проекта приложения ссылается на версию Microsoft.Maui.Controls пакета NuGet .NET 8 напрямую или через $(MauiVersion) свойство сборки, обновите его до версии .NET 9. Затем удалите ссылку на Microsoft.Maui.Controls.Compatibility пакет NuGet, если приложение не использует какие-либо типы из этого пакета. Кроме того, обновите ссылку на Microsoft.Extensions.Logging.Debug пакет NuGet до последнего выпуска .NET 9.

Если приложение предназначено для iOS или Mac Catalyst, обновите $(SupportedOSPlatformVersion) свойства сборки для этих платформ до 15.0:

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

При отладке и развертывании нового проекта MAUI .NET в Windows поведение по умолчанию в .NET 9 заключается в развертывании распаковки приложения. Сведения об использовании этого поведения см. в разделе "Преобразование упаковаированного приложения .NET MAUI Windows в распаковку".

Прежде чем впервые создать обновленное приложение, удалите bin папки и obj папки. Все ошибки сборки и предупреждения помогут вам выполнить следующие действия.

Обновление кодов ошибок компилятора XAML

Коды ошибок компилятора XAML изменили свой префикс на XFCXC , поэтому обновите $(WarningsAsErrors)$(WarningsNotAsErrors)свойства и $(NoWarn) сборку свойств в файле проекта приложения, если используется, чтобы ссылаться на новый префикс.

Устранение новых предупреждений компилятора XAML для скомпилированных привязок

Предупреждения сборки будут созданы для привязок, которые не используют скомпилированные привязки, и их необходимо устранить. Дополнительные сведения см . в предупреждениях о скомпилированных привязках XAML.

Обновление расширений разметки XAML

Расширения разметки XAML должны быть аннотированы либо с RequireServiceAttributeAcceptEmptyServiceProviderAttributeпомощью расширения разметки XAML. Это необходимо из-за оптимизации компилятора XAML, которая позволяет создавать более эффективный код, что помогает уменьшить размер приложения и повысить производительность среды выполнения. Дополнительные сведения см. в разделе "Поставщики услуг".

Нерекомендуемые API-интерфейсы адресов

.NET MAUI 9 не рекомендует некоторые API, которые будут полностью удалены в будущем выпуске. Поэтому устраняйте предупреждения о устаревших API сборки. Дополнительные сведения см. в разделе "Устаревшие API".

Принятие скомпилированных привязок, которые задают свойство Source

Вы можете выбрать компиляцию привязок, которые задают Source свойство, чтобы воспользоваться более эффективной производительностью среды выполнения. Дополнительные сведения см. в разделе "Компиляция привязок", определяющих Source свойство.

Внедрение скомпилированных привязок в C#

Вы можете выбрать компиляцию выражений привязки, объявленных в коде, чтобы воспользоваться преимуществами повышения производительности среды выполнения. Дополнительные сведения см. в разделе "Скомпилированные привязки" в коде.

Внедрение полной обрезки

Вы можете использовать полную обрезку, чтобы уменьшить общий размер приложения, задав $(TrimMode) для свойства MSBuild значение full. Дополнительные сведения см. в разделе Обрезать приложение .NET MAUI.

Внедрение развертывания NativeAOT на поддерживаемых платформах

Вы можете выбрать собственное развертывание AOT в iOS и Mac Catalyst. В собственном развертывании AOT создается приложение .NET MAUI, скомпилированное в машинный код. Дополнительные сведения см. в статье о развертывании Native AOT в iOS и Mac Catalyst.

.NET для Android

.NET для Android в .NET 9, который добавляет поддержку API 35, включает в себя работу, чтобы сократить время сборки, а также повысить обрезку приложений для уменьшения размера и повышения производительности. Дополнительные сведения о .NET для Android в .NET 9 см. в следующих заметках о выпуске:

Пакеты ресурсов

.NET для Android в .NET 9 представляет возможность поместить ресурсы в отдельный пакет, известный как пакет ресурсов. Это позволяет отправлять игры и приложения, которые обычно будут больше базового размера пакета, разрешенного Google Play. Поместив эти ресурсы в отдельный пакет, вы получаете возможность отправить пакет размером до 2 ГБ, а не базовый размер пакета 200 Мб.

Внимание

Пакеты ресурсов могут содержать только ресурсы. В случае с .NET для Android это означает элементы, которые имеют действие сборки AndroidAsset .

Приложения .NET MAUI определяют ресурсы с помощью действия сборки MauiAsset . Пакет ресурсов можно указать с помощью атрибута AssetPack :

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

Примечание.

Дополнительные метаданные будут игнорироваться другими платформами.

Если у вас есть определенные элементы, которые вы хотите разместить в пакете ресурсов, можно использовать Update атрибут для определения AssetPack метаданных:

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

Пакеты ресурсов могут иметь различные варианты доставки, которые управляют установкой ресурсов на устройстве:

  • Установка пакетов времени устанавливается одновременно с приложением. Этот тип пакета может быть размером до 1 ГБ, но у вас может быть только один из них. Этот тип доставки указан с метаданными InstallTime .
  • Быстрые пакеты будут устанавливаться в какой-то момент вскоре после завершения установки приложения. Приложение сможет запуститься, пока установлен этот тип пакета, поэтому перед попыткой использовать ресурсы необходимо проверить, что оно завершено. Этот тип пакета ресурсов может быть размером до 512 Мб. Этот тип доставки указан с метаданными FastFollow .
  • Пакеты по запросу никогда не будут загружаться на устройство, если приложение не запрашивает его. Общий размер всех пакетов ресурсов не может превышать 2 Гб, и вы можете иметь до 50 отдельных пакетов активов. Этот тип доставки указан с метаданными OnDemand .

В приложениях .NET MAUI тип доставки можно указать с помощью атрибута DeliveryType в MauiAsset:

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

Дополнительные сведения о пакетах активов Android см. в разделе "Пакеты активов Android".

Поддержка Android 15

.NET для Android в .NET 9 добавляет привязки .NET для Android 15 (API 35). Чтобы создать эти API, обновите целевую платформу проекта следующим net9.0-androidобразом:

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

Примечание.

Можно также указать net9.0-android35 в качестве целевой платформы, но число 35, вероятно, изменится в будущих выпусках .NET в соответствии с новыми выпусками ОС Android.

64-разрядные архитектуры по умолчанию

.NET для Android в .NET 9 больше не создает следующие идентификаторы среды выполнения (RID) по умолчанию:

  • android-arm
  • android-x86

Это должно улучшить время сборки и уменьшить размер файлов Android .apk . Обратите внимание, что Google Play поддерживает разделение пакетов приложений на архитектуру.

Если необходимо создать эти архитектуры, их можно добавить в файл проекта (CSPROJ):

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

Или в проекте с несколькими целевыми объектами:

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

Методы маршала Android

Улучшения методов маршала Android в .NET 9 сделали функцию более надежной в приложениях, но еще не является стандартной. Включение этой функции привело к улучшению производительности в тестовом приложении примерно на 10 %.

Методы маршала Android можно включить в файле проекта (CSPROJ) с помощью $(AndroidEnableMarshalMethods) свойства:

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

Дополнительные сведения о функции см. в документации по функциям или реализации на сайте GitHub.

Усовершенствования обрезки

В .NET 9 сборки API Android (Mono.Android.dll, Java.Interop.dll) теперь полностью совместимы. Чтобы выбрать полную обрезку, задайте $(TrimMode) свойство в файле проекта (CSPROJ):

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

Это также позволяет обрезать анализаторы, чтобы предупреждения появились для любого проблемного кода C#.

Дополнительные сведения см. в разделе "Обрезка детализации".

.NET для iOS

.NET 9 в iOS, tvOS, Mac Catalyst и macOS используют Xcode 16.0 для следующих версий платформы:

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

Дополнительные сведения о .NET 9 в iOS, tvOS, Mac Catalyst и macOS см. в следующих заметках о выпуске:

Привязки

.NET для iOS 9 представляет возможность многоцелевой версии .NET для привязок iOS. Например, проект библиотеки может потребоваться создать для двух разных версий iOS:

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

При этом будут создаваться две библиотеки, одна с помощью привязок iOS 17.0 и одна с помощью привязок iOS 17.2.

Внимание

Проект приложения всегда должен ориентироваться на последний пакет SDK для iOS.

Усовершенствования обрезки

В .NET 9 сборки iOS и Mac Catalyst (Microsoft.iOS.dll, Microsoft.MacCatalyst.dll и т. д.) теперь полностью совместимы. Чтобы выбрать полную обрезку, задайте $(TrimMode) свойство в файле проекта (CSPROJ):

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

Это также позволяет обрезать анализаторы, чтобы предупреждения появились для любого проблемного кода C#.

Дополнительные сведения см. в разделе "Обрезка детализации".

Собственный AOT для iOS и Mac Catalyst

В .NET для iOS 9 собственная компиляция накануне времени (AOT) для iOS и Mac Catalyst использует полную обрезку, чтобы уменьшить размер пакета приложения и производительность запуска. NativeAOT строится на основе полной обрезки, также выбрав новую среду выполнения.

Внимание

Приложение и это зависимости должны быть полностью обрезаны, чтобы использовать эту функцию.

NativeAOT требует, чтобы приложения были созданы с нулевыми предупреждениями обрезки, чтобы доказать, что приложение будет работать правильно во время выполнения.

См. также