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


Изменение поведения макета из Xamarin.Forms

При запуске обновленного многоплатформенного пользовательского интерфейса приложений .NET (.NET MAUI) поведение макета отличается. Некоторые из этих значений являются результатом изменений в значениях интервалов макета. Дополнительные сведения см. в разделе "Изменения значений по умолчанию" из Xamarin.Forms.

В следующей таблице показаны дополнительные изменения поведения между макетами в Xamarin.Forms и .NET MAUI:

Макет Xamarin.Forms .NET MAUI Рекомендация
Все В некоторых случаях запросы на изменение размера не учитываются. Запросы на изменение размера учитываются.
Grid Столбцы и строки можно вывести из XAML. Столбцы и строки должны быть явно объявлены. Добавьте ColumnDefinitions и RowDefinitions.
HorizontalStackLayout *AndExpand не имеет эффекта.
RelativeLayout Требуется пространство имен совместимости. Используйте Grid вместо этого или добавьте xmlns для пространства имен совместимости.
StackLayout Дочерние элементы могут заполнять пространство в направлении стека. Дочерние элементы стекаются и выходят за рамки доступного пространства. Если вам нужны дочерние представления для заполнения пространства, измените его на Grid.
VerticalStackLayout *AndExpand не имеет эффекта.

Элементы управления .NET MAUI обычно выполняют явные запросы на размер. Если вы попросите элемент управления иметь 200 единиц, независимых от устройств, то .NET MAUI сделает этот элемент управления 200 единиц широкий, даже если контейнер элемента управления имеет только 100 единиц ширины.

Изменение значения макета по умолчанию из Xamarin.Forms

Xamarin.Forms использует произвольные значения по умолчанию для некоторых значений свойств, таких как заполнение, поля и интервалы. .NET MAUI изменяет эти произвольные значения свойств на ноль.

Чтобы сохранить значения по умолчанию Xamarin.Forms в проектах, которые не задают явные значения, добавьте неявные стили в проект. Дополнительные сведения о неявных стилях см. в разделе "Неявные стили".

Примечание.

Шаблон проекта .NET MAUI включает словари ресурсов, которые предоставляют стили по умолчанию для большинства элементов управления. Рекомендуется использовать аналогичный подход в приложениях, изменив или наследуя их из этих словарей ресурсов.

В следующей таблице перечислены значения свойств макета, которые изменились между Xamarin.Forms и .NET MAUI:

Свойство Значение Xamarin.Forms Значение .NET MAUI
Grid.ColumnSpacing 6 0
Grid.RowSpacing 6 0
StackLayout.Spacing 6 0

Следующие стили сохраняют значения по умолчанию Xamarin.Forms:

<!-- Forms defaults -->
<Style TargetType="Grid">
    <Setter Property="ColumnSpacing" Value="6"/>
    <Setter Property="RowSpacing" Value="6"/>
</Style>
<Style TargetType="StackLayout">
    <Setter Property="Spacing" Value="6"/>
</Style>
<Style TargetType="Frame">
    <Setter Property="Padding" Value="{OnPlatform 20,iOS=19}"/>
</Style>

Кадр

Frame заменен в Border.NET MAUI. Однако она включается для упрощения миграции из Xamarin.Forms. Макет .NET MAUI правильно измеряется Frame Padding на всех платформах, в то время как Xamarin.Forms имеет некоторые несоответствия между платформами. Это может привести к тому, что приложения не выглядят одинаково в .NET MAUI. Приведенный выше пример учитывает это, если вы используете значения по умолчанию.

Сетка

Самое большое изменение поведения между Xamarin.Forms и .NET MAUI заключается в Grid том, что сетки не добавляют отсутствующие строки и столбцы для вас. Например, в Xamarin.Forms можно добавлять элементы управления в не Grid указывая их поведение строки:

<Grid>
    <Label Text="Hello"/>
    <Label Grid.Row="1" Text="World"/>
</Grid>

В Xamarin.Forms, несмотря на отсутствие объявления о том, что Grid содержит две строки, для вас будет автоматически добавлена вторая строка. Это не делает .NET MAUI. Вместо этого необходимо явно указать количество строк в свойстве Grid RowDefinitions .

Внимание

По умолчанию .NET MAUI создает один Grid столбец и одну строку. Поэтому не обязательно задавать ColumnDefinitions свойства, RowDefinitions если это ваше намерение.

В Xamarin.Forms, если Label столбец находится в столбце, где задана ширина его ColumnDefinition значения Auto, разрывы строк, такие как оболочка слов и усечение хвоста, неявно происходят. В .NET MAUI в этом сценарии разрывы строк не происходят неявно, так как столбец расширяется мимо ширины экрана для размещения содержимого дочернего элемента. Если вы хотите, чтобы оболочка Label была в краю Grid необходимо задать соответствующее ColumnDefinition * значение или значение.

StackLayout

Существует несколько различий между макетами стека в .NET MAUI (StackLayout, VerticalStackLayoutи HorizontalStackLayout) и StackLayout в Xamarin.Forms.

Основное различие заключается в том, что макеты стека .NET MAUI очень просты. Они стекают дочерние представления в одном направлении до тех пор, пока все из них не будут сложены. Они будут продолжать идти до тех пор, пока последний ребенок не будет сложен, даже если он принимает их за пределы доступного пространства в направлении стека. Поэтому макеты стека .NET MAUI упорядочивает элементы управления в определенном направлении. Они не подразделяют пространство. Это совершенно отличается от Xamarin.Forms StackLayout, которое изменяет его поведение макета в зависимости от обстоятельств и наличия любых *AndExpand параметров макета, таких как FillAndExpand или CenterAndExpand. Xamarin.Forms StackLayout иногда подразделяет пространство, расширяясь до или останавливаясь на краю контейнера. В других случаях он расширяется за пределы своего контейнера.

Новые макеты стека в .NET MAUI HorizontalStackLayout и VerticalStackLayoutне распознают параметры макета *AndExpand . Если они сталкиваются с ребенком с такими параметрами макета, они просто относятся к нему, как если AndExpand бы там не было. Например, FillAndExpand преобразуется в Fill. Однако для простоты миграции из Xamarin.Forms MAUI StackLayout .NET учитывает *AndExpand параметры макета, хотя они помечены как устаревшие. Чтобы избежать предупреждений об использовании устаревших элементов, следует преобразовать макеты, использующие *AndExpand параметры макета в соответствующий тип макета. Это можно сделать следующим образом:

  1. Если макет отличается от другогоStackLayoutAndExpand, удалите все использование. Как и в Xamarin.Forms, в .NET MAUI AndExpand параметры макета не влияют на любой макет, кроме StackLayout.

  2. Удалите все AndExpand свойства, которые являются ортогональными в направлении стека. Например, если у вас есть дочерний StackLayout Orientation Verticalобъект с дочерним элементом с параметром a HorizontalAligment="CenterAndExpand" - параметры макета не влияют и могут быть удалены.

  3. Если у вас есть оставшиеся AndExpand свойства в объекте StackLayout, необходимо преобразовать его StackLayout в Grid. Приложение Grid предназначено для делегировать пространство и предоставить макет, AndExpand предоставленный в Xamarin.Forms. В следующем примере показан объект Xamarin.Forms StackLayout , использующий AndExpand свойство:

    <StackLayout>
        <Label Text="Hello world!"/>
        <Image VerticalOptions="FillAndExpand" Source="dotnetbot.png"/>
    </StackLayout>
    

    Это можно преобразовать в Grid .NET MAUI:

    <Grid RowDefinitions="Auto, *">
        <Label Text="Hello world!"/>
        <Image Grid.Row="1" Source="dotnetbot.png"/>
    </Grid>
    

    При выполнении этого преобразования все, что было отмечено AndExpand в StackLayout строке или столбце с размером * в строке или столбце Grid.

Внимание

Направление StackLayout стека продолжается до тех пор, пока не закончится содержимое. Он не подразделяет контейнер вдоль этой оси. Если вы хотите ограничить содержимое ограниченным пространством в направлении, следует использовать другой макет, например Grid.

RelativeLayout

RelativeLayout Использование не рекомендуется в .NET MAUI. Вместо этого используйте везде, где Grid это возможно.

Если требуется абсолютное RelativeLayoutтребование, его можно найти в Microsoft.Maui.Controls.Compatibility пространстве имен:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:compat="clr-namespace:Microsoft.Maui.Controls.Compatibility;assembly=Microsoft.Maui.Controls"
             x:Class="MyMauiApp.MyPage"
             Title="MyPage">
    <compat:RelativeLayout>
        <!-- Your code goes here -->
    </compat:RelativeLayout>
</ContentPage>

ScrollView

Хотя ScrollView часто не считается макетом, его можно рассматривать как макет, так как он используется для прокрутки дочернего содержимого. В Xamarin.Forms ScrollView не ведет себя согласованно при стеке. Он имеет некоторые произвольные ограничения на минимальный размер, который частично зависит от его содержимого, и иногда сжимается, чтобы другие элементы могли помещаться на страницу внутри StackLayout способов, которые несогласованы и иногда удивительно.

В .NET MAUI расширяется ScrollView до любого размера, который он хочет быть, если иное не ограничено. Это означает, что внутри объекта, который может расширяться бесконечно, ScrollView будет расширяться до полной VerticalStackLayoutвысоты содержимого и не прокручивается. Это поведение может быть запутано, если вы являетесь пользователем Xamarin.Forms.