Grid でビューを配置する

完了

7x5 グリッドでイメージを表示するページを構築するとします。 複数の横方向と縦方向の StackLayout コンテナーを使用して、このページを作成することができます。 しかし、コーディングが面倒になり、複数のレイアウト パネルのメモリと処理の要件により、パフォーマンスの問題が発生する可能性があります。 Grid レイアウト パネルは、行と列の両方を必要とする UI により適した選択肢です。 このユニットでは、Grid を定義し、そのセル内にビューを配置する方法について学習します。

Grid とは

Grid は、行と列で構成されるレイアウト パネルです。 以下は、グリッドの概念図を示しています。

1 つのボックスが複数の行と列にまたがる、ボックスの行と列を持つグリッドの例を示す図。

行と列の交差部分から作成されるセルにビューを配置します。 たとえば、列が 3 つあり、行が 2 つある Grid を作成した場合、ビューで使用可能な 6 つのセルが存在することになります。 行と列を異なるサイズにすることも、その内部に配置されている子のサイズに応じて自動的に調整されるように設定することもできます。 子ビューでは単一のセルを占有することも、多くのセルにまたがるようにすることもできます。 この柔軟性により、Grid が、多くのアプリのルート レイアウト パネルに適した選択肢となります。

Grid の行と列を指定する方法

Grid を作成するときに、行と列をそれぞれ個別に定義できます。 このシステムによって、各行の高さと各列の幅を完全に制御できます。 すべての Grid に、グリッドの形状を定義する RowDefinition および ColumnDefinition オブジェクトのコレクションがあります。 これらのコレクションに、UI で行または列を表す RowDefinitionColumnDefinition のインスタンスを設定します。

以下は、RowDefinitionColumnDefinition のクラス定義を示すコードの 2 つのスニペットです。

public sealed class RowDefinition : ...
{
    ...
    public GridLength Height { get; set; }
}
public sealed class ColumnDefinition : ...
{
    ...
    public GridLength Width { get; set; }
}

RowDefinition には Height というプロパティがあり、ColumnDefinition には Width というプロパティがあることに注目してください。 次のセクションで説明するように、これらのプロパティを使って、行の高さと列の幅を設定します。

GridLength とは

Width および Height プロパティのデータ型は GridLength です。 この型には、GridUnitType および Value という 2 つのプロパティが含まれます。 以下は、型定義の一部を示すコードのスニペットです。

public struct GridLength
{
    ...
    public GridUnitType GridUnitType { get; }
    public double Value { get; }
}

GridUnitType プロパティをこれらの値のいずれかに設定することができます。

  • Absolute
  • Auto
  • Star

これらの各値について詳しく見ていきましょう。

Absolute GridUnitType

Absolute では、行または列のサイズが固定されるように指定します。 Value プロパティを使ってサイズを指定します。 以下は、C# で行の高さを 100 デバイス単位の固定サイズに設定する方法を示す例です。 数値を受け取る GridLength コンストラクターの使い方に注目してください。 このコンストラクターにより、GridUnitType は自動的に Absolute に設定されます。

var row = new RowDefinition() { Height = new GridLength(100) };

Extensible Application Markup Language (XAML) では、数値のみを指定します。 XAML パーサーによって、GridLength インスタンスを作成するために型コンバーターが呼び出されます。 以下は、XAML での同じことを示す例です。

<RowDefinition Height="100" />

Auto GridUnitType

Auto を使うと、子ビューに合わせて行または列のサイズが自動的に設定されます。 Grid を使って、その行または列内のすべての子ビューをスキャンし、最大のビューを選んでから、行または列をその子に合う十分な大きさにします。 コードで行の定義を作成するときに、数値は無視されます。 任意の値を使用できます。 以下は、C# で行の高さを自動的にサイズ設定する方法を示す例です。 1 という値が任意に選択されていることに注目してください。

var row = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };

XAML では、Auto という値を使用します。 以下は、XAML での同じことを示す例です。

<RowDefinition Height="Auto" />

Star GridUnitType

Star では比例サイズ指定が提供されます。 比例サイズ設定では、使用できる合計領域と、個々の行または列に必要な比率によってサイズが決まります。 会話では、多くの場合、これは "比例サイズ指定" ではなく、"スター サイズ指定" と呼ばれます。

グリッドの行の比例サイズ指定を使用するプロセスについて見ていきましょう。

  1. 使用可能なスペースを決定します。Grid では、スター サイズ指定を使用Gridすべての行をスキャンします。 これらすべての行の高さを合計し、Grid 自体の高さからその合計を減算します。 この計算では、スターサイズ指定されたすべての行で使用可能なスペースの量が提供されます。

  2. 使用可能なスペースを定義します。Grid では、その後、各行の Value 設定に基づいて、スターサイズ指定されたすべての行の間で使用可能なスペースが分割されます。 Value プロパティは、スター サイズ指定されたものとして定義されたすべての行の間で比率を決定する乗数と考えてください。 たとえば、スターサイズ指定された 2 つの行があり、両方の乗数が 1 である場合、それらに使用可能なスペースが等分されます。 しかし、それらのいずれかの Value が 2 である場合、スペースは他の 2 倍になります。

以下は、C# で行の高さを 2 Star に設定する方法を示す例です。

var row = new RowDefinition() { Height = new GridLength(2, GridUnitType.Star) };

XAML では、* シンボルを使用して、スター サイズ指定を表します。 値と * を単一の文字列に結合すると、型コンバーターによって自動的に GridLength が作成されます。 XAML での同じ例を次に示します。

<RowDefinition Height="2*" />

グリッド コレクション

RowDefinitionColumnDefinition を使って行と列を定義した後は、それらを Grid に追加できます。 Grid のコレクション プロパティ RowDefinitionsColumnDefinitions を使います。 これらのコレクションの設定は、通常 XAML で行います。

この例では、4 つの行を定義し、RowDefinitions プロパティを使用して、それらを Grid に追加する方法を示します。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="1*" />
        <RowDefinition Height="2*" />
    </Grid.RowDefinitions>
    ...
</Grid>

この定義は次のように短縮できます。

<Grid RowDefinitions="100, Auto, 1*, 2*">
    ...
</Grid>

列を定義するための XAML は、前の XAML に似ています。 ただし、ColumnDefinitions を使用し、Width を設定します。

実行時に、この XAML によって、4 行ある Grid が生成されます。 1 行目は 100 デバイス単位の固定の高さになります。 2 行目は行の最も高いビューの高さとなります。 3 行目と 4 行目にはスター サイズ指定が使われます。これは、残りの使用可能な領域を取得し、それをその Value 乗数に基づいて比例的に分割することを意味します。 3 行目が 1*、4 行目が 2* であるため、4 行目は 3 行目の高さの 2 倍です。

行と列の既定のサイズ

行と列の既定のサイズは 1* です。 たとえば、次の XAML を見てみましょう。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    ...
</Grid>

この定義は次のように短縮できます。

<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
    ...
</Grid>

行と列のサイズが指定されていないため、1* はそれらすべてに適用されます。 実行時に、この構成で均一の Grid が作成されます。これは、すべての行の高さが同じになり、すべての列の幅が同じになることを意味します。

Grid にビューを追加する方法

Grid にビューを追加するときは、特定のセルにそれを追加します。 セルは行と列が交差する位置に作成されます。 セルにビューを配置するには、セルの位置がわかっている必要があります。 行数と列数の組み合わせを使用して、セルを識別します。

行と列の番号付け

行と列の番号付けは 0 から始まります。 原点は左上隅です。 以下は、行が 4 つで列が 2 つの Grid の番号付けを示す図です。

行が 4 つあり、列が 2 つあるグリッドを示す図。各行と列に番号が表示されます。列 0、行 0 の左上のボックスから、列 1、行 3 の右下のボックスまで。

たとえば、右下のセルにビューを追加する場合、ビューの位置は row 3 column 1 になります。

添付プロパティを使用して Grid にビューを追加する

グリッドに追加するときは、ビューの行と列の番号を指定する方法が必要です。 1 つの解決策は、View 基底クラスで Row および Column プロパティを定義し、ビューでの位置を直接指定できるようにすることです。 この技法は機能しますが、最も効率的なアプローチではありません。 ビューが必ずしも Grid に含まれるわけではないため、それらのプロパティが不要な場合もあります。 添付プロパティを使用することをお勧めします。

添付プロパティとは、あるクラスで定義されているものの、他の種類のオブジェクトに対して設定されているプロパティのことです。

添付プロパティは、ビューの一部であるキーと値のペアのコレクションと考えてください。 ビューを Grid に追加するときは、行と列を指定します。 添付プロパティを使って、キー Grid.Row と、行番号を指定する値で、キーと値のペアを追加することができます。 Grid でビューを配置する準備ができると、コレクションで Grid.Row というキーがあるかどうかが確認されます。 ある場合、Grid ではその値を使って、ビューが配置されます。

この例では、添付プロパティを使用して、Grid を作成し、ビューを追加する方法を示します。

<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">

    <BoxView Grid.Row="1" Grid.Column="0" Color="Navy" />
    
</Grid>

この例では、Grid.Row=1Grid.Column=0 は、BoxView の内部コレクションに追加されるキーと値のペアです。 Grid ではそれらの値を使って、ビューを配置する必要がある場所を決定します。 デバイス上でアプリケーションを実行した場合、この Grid は次のようになります。

BoxView が最初の列の 2 行目に表示された、3 つの行と 2 つの列があるグリッドを示す図。

複数の行または列にまたがるビューを作成する方法

注意する必要がある、Grid.RowSpan および Grid.ColumnSpan というさらに 2 つの添付プロパティがあります。 これらのプロパティでは、ビューで占有する必要がある行または列の数が指定されます。 たとえば、次の XAML を見てみましょう。

<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">

    <BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Color="Navy" />
    
</Grid>

この例では ColumnSpan2 に設定していることに注意してください。 このビューは Column 0 から始まる 2 列を占有します。 デバイス上でアプリケーションを実行した場合、この Grid は次のようになります。

3 つの行と 2 つの列があるグリッドを示す図。BoxView は最初の列の 2 行目に配置され、両列に及んでいます。

知識チェック

1.

Star GridUnitType の目的は何ですか?