Xamarin.Forms からのレイアウト動作の変更

アップグレードされた .NET Multi-platform App UI (.NET MAUI) アプリを実行すると、レイアウトの動作が異なることに気づく場合があります。 その一部は、レイアウト間隔の値が変更された結果です 詳細については、「Xamarin.Forms からの既定値の変更」をご覧ください。

次の表は、Xamarin.Forms と .NET MAUI のレイアウト間の追加の動作の変更を示しています。

レイアウト Xamarin.Forms .NET MAUI 推奨事項
すべて サイズ変更要求が受け入れられない場合があります。 サイズ変更要求が受け入れられます。
Grid 列と行は XAML から推論できます。 列と行は明示的に宣言する必要があります。 ColumnDefinitionsRowDefinitions を追加します。
HorizontalStackLayout *AndExpand は効果がありません。
RelativeLayout 互換性名前空間が必要です。 代わりに Grid を使用するか、互換性名前空間に xmlns を追加します。
StackLayout 子は積み重ね方向の領域を埋めることができます。 子は積み重ねられ、使用可能な領域を超えます。 領域を埋める子ビューが必要な場合は Grid に変更します。
VerticalStackLayout *AndExpand は効果がありません。

.NET MAUI コントロールでは、通常、明示的なサイズ要求は受け入れられます。 デバイスに依存しない 200 単位の幅をコントロールに指定すると、コントロールのコンテナーの幅が 100 単位のみであっても、.NET MAUI はそのコントロールの幅を 200 単位にします。

Xamarin.Forms からの既定のレイアウト値の変更

Xamarin.Forms では、パディング、余白、間隔など、一部のプロパティ値に任意の既定値が使用されます。 .NET MAUI は、これらの任意のプロパティ値を 0 に変更します。

明示的な値を設定していないプロジェクトで Xamarin.Forms の既定値を保持するには、暗黙的なスタイルをプロジェクトに追加します。 暗黙的なスタイルの詳細については、「暗黙的なスタイル」をご覧ください。

Note

.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 は .NET MAUI では Border に置き換えられました。 ただし、Xamarin.Forms からの移行を容易にするために含まれています。 .NET MAUI レイアウトではすべてのプラットフォームで FramePadding が正しく測定されますが、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 に 2 つの行が含まれていることを宣言していないにもかかわらず、2 行目が自動的に追加されます。 .NET MAUI ではこれを行いません。 代わりに、RowDefinitions プロパティを使用して、Grid にある行数を明示的に指定する必要があります。

重要

.NET MAUI の既定では、1 つの列と 1 つの行を含む Grid が作成されます。 したがって、これが意図である場合は、ColumnDefinitions プロパティと RowDefinitions プロパティを設定する必要はありません。

StackLayout

.NET MAUI (StackLayoutVerticalStackLayoutHorizontalStackLayout) のスタック レイアウトと Xamarin.Forms の StackLayout には、いくつかの違いがあります。

主な違いは、.NET MAUI スタック レイアウトが非常に単純である点です。 すべての子ビューが積み上げられるまで、子ビューを 1 方向に積み上げます。 最後の子が積み上げられるまで、積み上げ方向の空き領域を超えて移動します。 したがって、.NET MAUI スタック レイアウトでは、コントロールが特定の方向に配置されます。 スペースは分割されません。 これは Xamarin.Forms StackLayout とは全く異なり、状況と FillAndExpandCenterAndExpand などの *AndExpand レイアウト オプションの有無に基づいてレイアウト動作が変更されます。 Xamarin.Forms StackLayout では、コンテナーの端に拡張または停止して、スペースを分割することがあります。 それ以外の場合は、コンテナーを超えて拡張されます。

.NET MAUI の新しいスタック レイアウトでは、HorizontalStackLayoutVerticalStackLayout*AndExpand レイアウト オプションを認識しません。 このようなレイアウト オプションを持つ子に遭遇した場合は、AndExpand が存在しないかのように扱うだけです。 たとえば、FillAndExpandFill になります。 ただし、Xamarin.Forms からの移行を簡単にするために、.NET MAUI StackLayout では *AndExpand レイアウト オプションが優先されますが、古いものとしてマークされています。 古いメンバーの使用に関する警告を回避するには、*AndExpand レイアウト オプションを使用するレイアウトを適切なレイアウトの種類に変換する必要があります。 これは次のように実現できます。

  1. レイアウトが StackLayout 以外の場合は、AndExpand の使用をすべて削除します。 Xamarin.Forms と同様に、.NET MAUI では、AndExpand レイアウト オプションは StackLayout 以外のレイアウトには影響しません。

  2. 積み上げ方向に直交する AndExpand プロパティをすべて削除します。 例えば、VerticalOrientation 付きの StackLayout を持ち、HorizontalAligment="CenterAndExpand" 付きの子を持つ場合、そのレイアウト オプションは効果がなく、削除できます。

  3. StackLayout に残りの AndExpand プロパティがある場合は、その StackLayoutGrid に変換する必要があります。 Grid はスペースを分割するように設計されており、Xamarin.Forms で AndExpand によって提供されるレイアウトを提供します。 次の例は、AndExpand プロパティを使用する Xamarin.Forms StackLayout を示しています。

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

    これは、.NET MAUI で Grid に変換できます。

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

    この変換を実行する場合は、StackLayoutAndExpand とマークされた内容は、Grid でサイズが * の独自の行または列に入る必要があります。

重要

StackLayout は、コンテンツが不足するまで積み上げ方向に進みます。 その軸に沿ってコンテナーが分割されることはありません。 コンテンツを方向の制限されたスペースに制限する場合は、Grid のような別のレイアウトを使用する必要があります。

RelativeLayout

.NET MAUI では、RelativeLayout を使用しないことをお勧めします。 代わりに、可能な限り 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 は特に制約がない限り、任意のサイズに拡張されます。 つまり、無限に拡張できる VerticalStackLayout 内では、ScrollView は完全なコンテンツの高さに拡張され、スクロールしません。 Xamarin.Forms ユーザーの場合、この動作は混乱を招く可能性があります。