Layout behavior changes from Xamarin.Forms
You may notice when running your upgraded .NET Multi-platform App UI (.NET MAUI) app that layout behavior is different. Some of this is the result of changes to layout spacing values. For more information, see Default value changes from Xamarin.Forms.
The following table shows additional behavior changes between layouts in Xamarin.Forms and .NET MAUI:
Layout | Xamarin.Forms | .NET MAUI | Recommendation |
---|---|---|---|
All | In certain cases sizing requests aren't honored. | Sizing requests are honored. | |
Grid | Columns and rows can be inferred from XAML. | Columns and rows must be explicitly declared. | Add ColumnDefinitions and RowDefinitions. |
HorizontalStackLayout | *AndExpand has no effect. |
||
RelativeLayout | Requires the compatibility namespace. | Use Grid instead, or add the xmlns for the compatibility namespace. |
|
StackLayout | Children can fill space in the stacking direction. | Children are stacked and will go beyond available space. | If you need child views to fill space, change to a Grid. |
VerticalStackLayout | *AndExpand has no effect. |
.NET MAUI controls generally honour explicit size requests. If you ask a control to be 200 device-independent units wide, then .NET MAUI will make that control 200 units wide, even if the control's container is only 100 units wide.
Default layout value changes from Xamarin.Forms
Xamarin.Forms uses arbitrary default values for some property values, such as padding, margins, and spacing. .NET MAUI changes these arbitrary property values to zero.
To preserve the Xamarin.Forms default values in projects that don't set explicit values, add implicit styles to your project. For more information about implicit styles, see Implicit styles.
Note
The .NET MAUI project template includes resource dictionaries that provide default styles for most controls. It's recommended you take a similar approach in your apps, by modifying or inheriting from these resource dictionaries.
The following table lists the layout property values that have changed between Xamarin.Forms and .NET MAUI:
Property | Xamarin.Forms value | .NET MAUI value |
---|---|---|
Grid.ColumnSpacing |
6 | 0 |
Grid.RowSpacing |
6 | 0 |
StackLayout.Spacing |
6 | 0 |
The following styles retain the Xamarin.Forms defaults:
<!-- 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
Frame has been replaced in .NET MAUI by Border. However, it's included to ease migration from Xamarin.Forms. .NET MAUI layout correctly measures Frame Padding
across all platforms, whereas Xamarin.Forms had some discrepancies across platforms. This may result in your apps not looking the same in .NET MAUI. The example above accounts for this if you're using default values.
Grid
The biggest change in Grid behavior between Xamarin.Forms and .NET MAUI is that grids don't automatically add missing rows and columns for you. For example, in Xamarin.Forms you could add controls to a Grid without specifying their row behavior:
<Grid>
<Label Text="Hello"/>
<Label Grid.Row="1" Text="World"/>
</Grid>
In Xamarin.Forms, despite not declaring that the Grid contains two rows, a second row would be automatically added for you. .NET MAUI doesn't do this. Instead, you have to explicitly specify how many rows are in the Grid with the RowDefinitions
property.
Important
By default, .NET MAUI creates a Grid with one column and one row. Therefore, it's not necessary to set the ColumnDefinitions
and RowDefinitions
properties if this is your intention.
StackLayout
There are several differences between the stack layouts in .NET MAUI (StackLayout, VerticalStackLayout, and HorizontalStackLayout) and the StackLayout
in Xamarin.Forms.
The main difference is that .NET MAUI stack layouts are very simple. They stack their child views in a single direction until all of them have been stacked. They will keep going until the last child has been stacked, even if that takes them beyond the available space in the stacking direction. Therefore, .NET MAUI stack layouts arrange controls in a particular direction. They do not subdivide a space. This is completely different to the Xamarin.Forms StackLayout
, which changes its layout behavior based on circumstances and the presence of any *AndExpand
layout options, such as FillAndExpand
or CenterAndExpand
. The Xamarin.Forms StackLayout
sometimes subdivides the space, expanding to or stopping at the edge of its container. In other cases, it expands beyond its container.
The new stack layouts in .NET MAUI, HorizontalStackLayout and VerticalStackLayout, do not recognize the *AndExpand
layout options. If they encounter a child with such layout options, they simply treat it as if the AndExpand
wasn't there. For example, FillAndExpand
becomes Fill
. However, for simplicity of migration from Xamarin.Forms, the .NET MAUI StackLayout does honor the *AndExpand
layout options, although they've been marked as obsolete. To avoid warnings about using obsolete members, you should convert your layouts that use *AndExpand
layout options to the appropriate layout type. The can be achieved as follows:
If your layout is anything other than a StackLayout, remove all uses of
AndExpand
. Just as in Xamarin.Forms, in .NET MAUI theAndExpand
layout options have no effect on any layout other than StackLayout.Remove any
AndExpand
properties which are orthogonal to the stacking direction. For example, if you have a StackLayout with anOrientation
ofVertical
, and it has a child with aHorizontalAligment="CenterAndExpand"
- that layout options has no effect and can be removed.If you have any remaining
AndExpand
properties on a StackLayout, you should convert that StackLayout to a Grid. A Grid is designed to subdivide a space, and will provide the layout thatAndExpand
provided in Xamarin.Forms. The following example shows a Xamarin.FormsStackLayout
that uses anAndExpand
property:<StackLayout> <Label Text="Hello world!"/> <Image VerticalOptions="FillAndExpand" Source="dotnetbot.png"/> </StackLayout>
This can be converted to a Grid in .NET MAUI:
<Grid RowDefinitions="Auto, *"> <Label Text="Hello world!"/> <Image Grid.Row="1" Source="dotnetbot.png"/> </Grid>
When performing this conversion, anything that was marked
AndExpand
in theStackLayout
should go in its own row or column with a size of*
in the Grid.
Important
A StackLayout continues in its stacking direction until it runs out of content. It does not subdivide its container along that axis. If you want to limit your content to a constrained space in a direction, you should use another layout such as a Grid.
RelativeLayout
Use of RelativeLayout is not recommended in .NET MAUI. Instead, use a Grid wherever possible.
If you absolutely require a RelativeLayout, it can be found in the Microsoft.Maui.Controls.Compatibility
namespace:
<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
While ScrollView often isn't considered to be a layout, it can be thought of as a layout as it's used to scroll its child content. In Xamarin.Forms, ScrollView
doesn't behave consistently when stacking. It has some arbitrary limits on minimum size that depend partially on its content, and it will sometimes compress to enable other items to fit on the page inside a StackLayout
in ways that are inconsistent and sometimes surprising.
In .NET MAUI, the ScrollView expands to whatever size it wants to be unless otherwise constrained. This means that inside of a VerticalStackLayout, which can expand infinitely, a ScrollView will expand to its full content height and doesn't scroll. This behavior can be confusing if you're a Xamarin.Forms user.
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for