以 Grid 排列檢視

已完成

假設您正在建置以 7 x 5 個方格顯示影像的網頁。 可以使用多個水平及垂直 StackLayout 容器來建立此頁面。 但撰寫程式碼很麻煩,且可能會因為多個版面配置面板的記憶體和處理需求而造成效能問題。 對於同時需要資料列和資料行的 UI,Grid 版面配置面板是更佳的選擇。 本單元中,您會了解如何定義 Grid,並在其資料格內定位檢視。

什麼是 Grid?

Grid 是一個由資料列和資料行組成的版面配置面板。 下圖顯示 Grid 的概念性概觀。

圖例顯示的範例方格,包含方塊的資料列和資料行,其中有一個方塊橫跨多個資料列和資料行。

您可將檢視放置在建立於資料列和資料行交集處的資料格中。 例如,如果您建立一個具有三個資料行與兩個資料列的 Grid,則會有六個資料格可供檢視使用。 資料列和資料行可以是不同的大小,或它們可以設定成自動調整為其內所放置子系的大小。 子檢視可以佔用單一資料格,或跨越多個資料格。 這種彈性讓 Grid 成為許多應用程式內主要版面配置面板的理想選擇。

如何指定 Grid 的資料列和資料行

當您建立 Grid 時,您可以個別定義每一個資料列和每一個資料行。 此系統可讓您完全控制每個資料列高度和每個資料行寬度。 每個 Grid 有一個 RowDefinitionColumnDefinition 物件的集合,用來定義 Grid 的形狀。 您使用 RowDefinitionColumnDefinition 執行個體填入這些集合,每個均代表 UI 中的資料列或資料行。

以下是兩個程式碼片段,其顯示 RowDefinitionColumnDefinition 的類別定義:

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

請注意,RowDefinition 具有稱為 Height 的屬性,而 ColumnDefinition 具有稱為 Width 的屬性。 您可以使用這些屬性來設定資料列高度和資料行寬度,如下列各節所述。

什麼是 GridLength?

WidthHeight 屬性的資料類型為 GridLength。 此類型包含兩個屬性:GridUnitTypeValue。 以下是顯示一部分類型定義的程式碼片段。

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 可讓您依比例調整大小。 在按比例調整大小時,總可用空間和每個資料列或資料行所需的比例可決定大小。 在談話中,人們經常將這個稱為「星型調整大小」,而不是「按比例調整大小」

讓我們逐步解說為 Grid 中資料列使用按比例調整大小的程序。

  1. 決定可用空間:Grid 會掃描使用星號調整的所有資料列。 它會加總所有資料列的高度,並從 Grid 本身的高度減去該總數。 此計算提供可用於所有星形調整大小資料列的空間數量。

  2. 分割可用的空間:Grid 接著會根據每個資料列的 Value 設定,劃分所有星形調整大小資料列之間的可用空間。 將 Value 屬性視為乘數,以判斷定義為星形調整大小的所有資料列之間比例。 例如,若我們有兩個星形調整大小資料列,兩者都會使用 1 作為乘數,可用空間將會在它們之間平均分割。 但是,如果其中一個使用 2 作為值,就會取得其他資料列兩倍的空間。

以下範例顯示您如何使用 C# 將資料列的高度設定為 2 Star

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

在 XAML 中,您可以使用 * 符號來代表星形調整大小。 您可以將值和 * 結合成單一字串,類型轉換器就會為您建立 GridLength。 以下是使用 XAML 的相同範例。

<RowDefinition Height="2*" />

Grid 集合

在您使用 RowDefinitionColumnDefinition 定義了資料列和資料行之後,您可以將其新增到 Grid。 您可以使用 GridRowDefinitionsColumnDefinitions 集合屬性。 通常會在 XAML 中填入這些集合。

此範例示範如何使用 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 會產生一個具有四個資料列的 Grid。 第一個資料列具有 100 個裝置單位的固定高度。 第二個資料列具有該資料列中最高檢視的高度。 第三個和第四個資料列使用了星形調整大小,這意味著它們佔用了剩餘的可用空間並根據其 Value 乘數按比例劃分它。 因為第三個資料列為 1* 而第四個資料列為 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 時,會將其新增至特定的資料格。 資料格會建立在資料列和資料行交集處的位置。 若要將檢視放置在資料格中,您需要知道資料格的位置。 您可以使用資料列編號和資料行編號的組合來識別資料格。

資料列和資料行編號

資料列和資料行的編號會從零開始。 原點是左上角。 以下圖例會顯示四個資料列和兩個資料行的 Grid 編號。

圖例顯示由四個資料列和兩個資料行所構成的方格。每一欄和每一行都會顯示編號。從位於第零欄和第零列的左上方塊開始,到位於第 1 欄和第 3 列的右下方塊。

例如,若想要將檢視新增至右下的資料格中,我們可以說檢視位在 row 3 column 1

使用附加屬性將檢視新增至 Grid

當您將檢視新增至 Grid 時,需要一種方法來指定檢視的資料列和資列行編號。 其中一個方案是要在 View 基底類別上定義 RowColumn 屬性,以便您可以直接在檢視上指定位置。 這項技術能夠運作,但它不是最有效率的方式。 檢視不一定會處於 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 會顯示在第一個資料行的第二個資料列中。

如何讓檢視跨越多個資料列或資料行

有兩個您應該要注意的附加屬性:Grid.RowSpanGrid.ColumnSpan。 這些屬性會指定檢視應佔用的資料列或資料行數目。 例如,請查看下列 XAML。

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

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

請注意,此範例會將 ColumnSpan 設定為 2。 此檢視佔用了從 Column 0 開始的兩個資料行。 如果您在裝置上執行應用程式,Grid 看起來會像這樣。

圖例顯示由三個資料列和兩個資料行所構成的格線。BoxView 放置在第一個資料行的第二個資料列中,並跨越兩個資料行。

知識檢查

1.

Star GridUnitType 的用途為何?