版面配置面板是容器,可讓您在應用程式中排列和分組 UI 元素。 內建的 XAML 版面配置面板包括 RelativePanel、 StackPanel、 Grid、 VariableSizedWrapGrid 和 Canvas。 在這裡,我們將說明每個面板,並示範如何使用它來配置 XAML UI 元素。
選擇佈局面板時需要考慮以下幾點:
- 面板如何排列其子元素。
- 面板如何設定其子元素的大小。
- 重疊子元素如何彼此分層 (z 順序)。
- 建立所需版面配置所需的巢狀面板元素的數量和複雜度。
範例
WinUI 3 Gallery 應用程式包含大部分 WinUI 3 控制項、特性和功能的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼
面板屬性
在討論各個面板之前,讓我們先回顧一下所有面板都具有的一些共同屬性。
面板附加屬性
大部分的 XAML 版面配置面板都會使用附加屬性,讓其子元素通知父面板應該如何在 UI 中放置它們。 附加屬性使用語法 AttachedPropertyProvider.PropertyName。 如果您有巢狀在其他面板中的面板,則 UI 元素上指定版面配置特性的附加屬性只會由最直接的父面板解譯。
以下是如何在 XAML 中的 Button 控制項上設定 Canvas.Left 附加屬性的範例。 這會通知父 Canvas,按鈕應位於距 Canvas 左邊緣 50 個有效像素之處。
<Canvas>
<Button Canvas.Left="50">Hello</Button>
</Canvas>
有關附加屬性的詳細資訊,請參閱附加屬性概觀。
面板邊框
RelativePanel、StackPanel 和 Grid 面板會定義框線屬性,可讓您在面板周圍繪製框線,而不需要將它們包裝在其他 Border 元素中。 邊框屬性是 BorderBrush、 BorderThickness、 CornerRadius 和 Padding。
以下是如何在 Grid 上設定邊框屬性的範例。
<Grid BorderBrush="Blue" BorderThickness="12" CornerRadius="12" Padding="12">
<TextBlock Text="Hello World!"/>
</Grid>
使用內建框線屬性可減少 XAML 元素計數,進而改善應用程式的 UI 效能。 如需版面配置面板和 UI 效能的詳細資訊,請參閱 最佳化 XAML 版面配置。
相對面板
RelativePanel 可讓您指定 UI 元素相對於其他元素和面板的位置,以配置 UI 元素。 依預設,元素會位於面板的左上角。 您可以將 RelativePanel 與 VisualStateManager 和 AdaptiveTrigger 搭配使用,針對不同的視窗大小重新排列 UI。
下表顯示可用來對齊元素相對於面板或其他元素的附加性質。
| 面板對齊 | 兄弟姊妹對齊 | 兄弟姊妹位置 |
|---|---|---|
| AlignTopWithPanel | 頂部對齊於 | 上面 |
| 對齊底部與面板 | 與底部對齊 | 下面 |
| AlignLeftWithPanel | 向左對齊 | 左側的 |
| 與面板右對齊 | 右對齊至 | 權利 |
| 與面板水平中心對齊 | AlignHorizontalCenterWith | |
| AlignVerticalCenterWithPanel | AlignVerticalCenterWith |
此 XAML 示範如何在 RelativePanel 中排列元素。
<RelativePanel BorderBrush="Gray" BorderThickness="1">
<Rectangle x:Name="RedRect" Fill="Red" Height="44" Width="44"/>
<Rectangle x:Name="BlueRect" Fill="Blue"
Height="44" Width="88"
RelativePanel.RightOf="RedRect" />
<Rectangle x:Name="GreenRect" Fill="Green"
Height="44"
RelativePanel.Below="RedRect"
RelativePanel.AlignLeftWith="RedRect"
RelativePanel.AlignRightWith="BlueRect"/>
<Rectangle Fill="Orange"
RelativePanel.Below="GreenRect"
RelativePanel.AlignLeftWith="BlueRect"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.AlignBottomWithPanel="True"/>
</RelativePanel>
結果如下所示。
以下是有關矩形大小的一些注意事項:
- 紅色矩形的明確大小為 44x44。 它位於面板的左上角,這是預設位置。
- 綠色矩形的明確高度為 44。 它的左側與紅色矩形對齊,其右側與藍色矩形對齊,藍色矩形決定了它的寬度。
- 橘色矩形不會提供明確的大小。 它的左側與藍色矩形對齊。 它的右邊緣和底部邊緣與面板邊緣對齊。 其大小由這些對齊方式決定,並且會隨著面板大小的調整而調整大小。
StackPanel
StackPanel 會將其子元素排列成可以水平或垂直方向的單行。 StackPanel 通常用來在頁面上排列 UI 的小型子區段。
您可以使用 Orientation 屬性來指定子元素的方向。 預設方向為垂直。
下列 XAML 示範如何建立垂直排列項目的 StackPanel。
<StackPanel>
<Rectangle Fill="Red" Height="44"/>
<Rectangle Fill="Blue" Height="44"/>
<Rectangle Fill="Green" Height="44"/>
<Rectangle Fill="Orange" Height="44"/>
</StackPanel>
結果如下所示。
在 StackPanel 中,如果未明確設定子元素的大小,它會延伸以填滿可用的寬度 (或高度,如果 Orientation 是 Horizontal) 。 在此範例中,未設定矩形的寬度。 矩形會展開以填滿 StackPanel 的整個寬度。
Grid
格子 面板支援流體版面配置,並可讓您用多列及多欄版面配置排列控制項。 您可以使用 RowDefinitions 和 ColumnDefinitions 屬性來指定方格的資料列和資料行。
若要將物件放置在 Grid 的特定儲存格中,請使用 Grid.Column 和 Grid.Row 附加屬性。
若要讓內容跨越多個資料列和資料行,請使用 Grid.RowSpan 和 Grid.ColumnSpan 附加屬性。
此 XAML 範例示範如何建立具有兩列和兩欄的 Grid。
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="44"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Fill="Red" Width="44"/>
<Rectangle Fill="Blue" Grid.Row="1"/>
<Rectangle Fill="Green" Grid.Column="1"/>
<Rectangle Fill="Orange" Grid.Row="1" Grid.Column="1"/>
</Grid>
結果如下所示。
在此範例中,大小調整的運作方式如下:
- 第二列的明確高度為 44 個有效像素。 依預設,第一列的高度會填滿剩餘的任何空間。
- 第一欄的寬度設定為 Auto,因此其寬度視其子項的需求而定。 在此情況下,它的寬度為 44 個有效像素,以容納紅色矩形的寬度。
- 矩形上沒有其他大小限制,因此每個矩形都會拉伸以填充它所在的網格單元格。
您可以使用 「自動 」或「星形大小調整」來分配欄或列內的空間。 您可以使用自動調整大小,讓 UI 元素調整大小,以符合其內容或父容器。 您也可以對網格的列和欄使用自動調整尺寸。 若要使用自動調整大小,請將 UI 元素的 [高度] 和/或 [寬度] 設定為 [自動]。
您可以使用比例大小 (也稱為 星形大小) 來依加權比例在網格的列和欄之間分配可用空間。 在 XAML 中,星號值會以 * (或 n* 表示加權星形大小) 表示。 例如,若要指定 2 欄配置中一欄比第二欄寬 5 倍,請針對 ColumnDefinition 元素中的 Width 屬性使用 “5*” 和 “*”。
此範例將固定、自動和比例大小的設置組合在具有 4 欄的 網格 中。
| 資料行 | 尺寸 | Description |
|---|---|---|
| Column_1 | 自動 | 該列的大小將適合其內容。 |
| Column_2 | * | 計算 Auto 資料行之後,該資料行會取得剩餘寬度中的一部分。 Column_2的寬度將是Column_4的二分之一。 |
| Column_3 | 44 | 該列的寬度為 44 像素。 |
| 欄_4 | 2* | 計算 Auto 資料行之後,該資料行會取得剩餘寬度中的一部分。 Column_4的寬度將是Column_2的兩倍。 |
預設資料行寬度為 “*”,因此您不需要為第二資料行明確設定此值。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="44"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Column 1 sizes to its content." FontSize="24"/>
</Grid>
在 Visual Studio XAML 設計工具中,結果如下所示。
可變尺寸環繞網格
VariableSizedWrapGrid 是一個 Grid 樣式的佈局面板,當達到 MaximumRowsOrColumns 值時,列或欄會自動折行為新的列或欄。
Orientation 屬性指定網格是在換行之前,按照列或欄新增其項目。 預設方向為 「垂直」,這表示格點會從上到下新增項目,直到欄已滿為止,然後換行到新欄。 當值為 「水平」時,格線會從左到右新增項目,然後換行至新列。
儲存格維度由 ItemHeight 和 ItemWidth 指定。 每個單元格的大小相同。 如果未指定 ItemHeight 或 ItemWidth,則第一個儲存格的大小會符合其內容,而其他每個儲存格都是第一個儲存格的大小。
您可以使用 VariableSizedWrapGrid.ColumnSpan 和 VariableSizedWrapGrid.RowSpan 附加屬性來指定子元素應填滿的相鄰儲存格數目。
以下是在 XAML 中使用 VariableSizedWrapGrid 的方法。
<VariableSizedWrapGrid MaximumRowsOrColumns="3" ItemHeight="44" ItemWidth="44">
<Rectangle Fill="Red"/>
<Rectangle Fill="Blue"
VariableSizedWrapGrid.RowSpan="2"/>
<Rectangle Fill="Green"
VariableSizedWrapGrid.ColumnSpan="2"/>
<Rectangle Fill="Orange"
VariableSizedWrapGrid.RowSpan="2"
VariableSizedWrapGrid.ColumnSpan="2"/>
</VariableSizedWrapGrid>
結果如下所示。
在此範例中,每欄中的列數上限為 3。 第一欄僅包含 2 個項目 (紅色和藍色矩形),因為藍色矩形跨越 2 列。 然後,綠色矩形會移到下一欄頂端。
畫布
「畫布」面板使用固定座標點來定位其子元素,且不支援流體版面配置。 您可以在每個元素上設定 Canvas.Left 和 Canvas.Top 附加屬性,以指定個別子元素上的點。 父 Canvas 會在佈局的 Arrange 階段期間,從其子系讀取這些附加屬性值。
畫布中的物件可以重疊,其中一個物件繪製在另一個物件之上。 根據預設,Canvas 會依宣告子物件的順序轉譯子物件,因此最後一個子物件會轉譯在頂端 (每個元素的預設 z 索引為 0)。 這與其他內建面板相同。 不過,Canvas 也支援您可以在每個子元素上設定的 Canvas.ZIndex 附加屬性。 您可以在程式碼中設定此屬性,以變更執行時間期間元素的繪製順序。 具有最高 Canvas.ZIndex 值的元素會最後繪製,因此會繪製共用相同空間或以任何方式重疊的任何其他元素。 請注意,alpha 值(透明度)會被應用,所以即使元素重疊,若頂部的元素具有非最大 alpha 值,重疊區域顯示的內容可能會混合。
Canvas 不會對其子項進行任何尺寸調整。 每個元素都必須指定其大小。
以下是 XAML 中的 Canvas 範例。
<Canvas Width="120" Height="120">
<Rectangle Fill="Red" Height="44" Width="44"/>
<Rectangle Fill="Blue" Height="44" Width="44" Canvas.Left="20" Canvas.Top="20"/>
<Rectangle Fill="Green" Height="44" Width="44" Canvas.Left="40" Canvas.Top="40"/>
<Rectangle Fill="Orange" Height="44" Width="44" Canvas.Left="60" Canvas.Top="60"/>
</Canvas>
結果如下所示。
謹慎使用「畫布」面板。 雖然在某些情況下能夠精確控制 UI 中元素的位置很方便,但固定定位的版面配置面板會導致 UI 的該區域對整體應用程式視窗大小變更的適應性較差。 應用程式視窗大小調整可能來自裝置方向變更、分割應用程式視窗、變更監視器,以及許多其他使用者案例。
ItemsControl 的專用面板
有數個特殊用途面板只能作為 ItemsPanel 使用,以顯示 ItemsControl 中的項目。 這些是 ItemsStackPanel、 ItemsWrapGrid、 VirtualizingStackPanel 和 WrapGrid。 您無法將這些面板用於一般 UI 配置。
取得範例程式碼
- WinUI 資源庫範例 - 以互動式格式查看所有 XAML 控制項。