WPF 強大的佈局系統是打造精美、自適應 UI 的基石。本文系統梳理 11 種核心 Panel 的特性與適用場景,提供 XAML 與 C# 雙模式代碼對照,並深入講解佈局遞歸原理、Measure/Arrange 兩階段機制,最後示範如何繼承 Panel 開發自訂佈局控件,助你駕馭複雜 UI 需求。
WPF 佈局為遞歸兩階段流程:
Measure(availableSize),子元素回報 DesiredSize。父元素根據所有子元素期望大小計算自身需求。finalRect,呼叫子元素 Arrange(finalRect) 確定位置與大小。自訂 Panel 僅需覆寫 MeasureOverride 與 ArrangeOverride 即可注入佈局邏輯。理解此機制是效能調優與自訂佈局的關鍵。
子元素透過附加屬性 Canvas.Left、Canvas.Top、Canvas.ZIndex 精確定位。不自動佈局、不裁切溢出內容(ClipToBounds=False 預設)。適合繪圖、拖放、遊戲場景。
Orientation 決定水平/垂直堆疊。子元素在堆疊方向佔據所需空間,垂直方向拉伸填滿。超出邊界內容被裁切。適合工具列、表單欄位、簡單清單。
類似 StackPanel 但會在邊界處自動換行/換列。Orientation 控制流向。適合標籤雲、圖片牆、動態按鈕群。
子元素用 DockPanel.Dock 附加屬性停靠四邊(Top/Bottom/Left/Right),最後一個子元素預設填滿剩餘區域(LastChildFill=True)。適合經典「頂部選單+底部狀態列+左側導航+右側內容」頁面架構。
最強大、最常用。透過 RowDefinitions/ColumnDefinitions 定義列/行,支援三種尺寸模式:
2* 佔 2/3)子元素用 Grid.Row、Grid.Column、RowSpan、ColumnSpan 定位。搭配 GridSplitter 實現可調整分割欄。
Grid 簡化版:所有儲存格等寬等高,自動按子元素數量計算行列。適合計算機鍵盤、九宮格選單。
單一子元素,依 Stretch(None/Fill/Uniform/UniformToFill)與 StretchDirection 縮放填滿可用空間。適合圖示、向量圖形、響應式縮放 UI。
單一子元素,提供 BorderBrush、BorderThickness、CornerRadius、Padding、Background。常作為其他 Panel 外層修飾。
單一子元素,提供水平/垂直捲軸(HorizontalScrollBarVisibility/VerticalScrollBarVisibility:Auto/Visible/Hidden/Disabled)。內容超出視口時自動啟用滾動。
結合 DockPanel(整體架構)+ Menu(頂部)+ StackPanel(底部狀態列+左側導航)+ Grid(右側內容區 2×2 卡片):
<DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top" />
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" />
<StackPanel DockPanel.Dock="Left" Width="136" />
<Grid>
<Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions>
<Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" /> ... </Grid>
</DockPanel>
自訂佈局直接繼承 System.Windows.Controls.Panel;需包含裝飾效果則繼承 Decorator;需項目呈現繼承 ItemsControl。
public class PlotPanel : Panel {
protected override Size MeasureOverride(Size availableSize) {
Size desired = new Size();
foreach (UIElement child in InternalChildren) {
child.Measure(availableSize);
desired = child.DesiredSize; // 簡單取最後一個
}
return desired;
}
protected override Size ArrangeOverride(Size finalSize) {
foreach (UIElement child in InternalChildren) {
child.Arrange(new Rect(new Point(50, 50), child.DesiredSize));
}
return finalSize;
}
}
MeasureOverride/ArrangeOverride 實作核心邏輯UpdateLayout() 強制重排VirtualizingPanel.IsVirtualizing=True)LayoutInformation.GetLayoutSlot 除錯佈局矩形精通 WPF 佈局系統,能讓你用最少代碼實現最複雜的自適應 UI。建議從掌握 Grid/StackPanel/DockPanel 黃金組合開始,再逐步探索自訂 Panel 的無限可能。