首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 筆記:自定義佈局容器 (MeasureOverride/ArrangeOverride)

     編輯:關於.NET

WPF 佈局系統核心在於兩階段協商:**Measure (測量)** 與 **Arrange (排列)**。自定義 Panel 必須覆寫 MeasureOverride 與 ArrangeOverride,並確保遍歷所有子元素呼叫其 Measure 與 Arrange 方法。

核心原則

  • MeasureOverride(availableSize):告訴父容器「我需要多大空間」。遍歷子元素呼叫 child.Measure(Size),回傳總需求尺寸。
  • ArrangeOverride(finalSize):父容器分配確定尺寸後,安排子元素具體位置。遍歷子元素呼叫 child.Arrange(Rect),回傳實際使用尺寸。
  • 不可跳過任何子元素:否則該元素不會參與佈局,導致不顯示或異常。

範例:DiagonalPanel (對角線排列)

將子元素沿對角線依次排列,每個元素右下偏移自身大小。

using System;
using System.Windows;
using System.Windows.Controls;

namespace CustomPanel {
    public class DiagonalPanel : Panel {
        // 測量階段:累加所有子元素寬高
        protected override Size MeasureOverride(Size availableSize) {
            double totalWidth = 0, totalHeight = 0;
            foreach (UIElement child in Children) {
                // 給子元素無限大空間讓其測量自有需求尺寸
                child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                Size childSize = child.DesiredSize;
                totalWidth += childSize.Width;
                totalHeight += childSize.Height;
            }
            return new Size(totalWidth, totalHeight);
        }

        // 排列階段:依序定位
        protected override Size ArrangeOverride(Size finalSize) {
            Point currentPos = new Point(0, 0);
            foreach (UIElement child in Children) {
                Rect childRect = new Rect(currentPos, child.DesiredSize);
                child.Arrange(childRect); // 實際安排位置
                currentPos.Offset(childRect.Width, childRect.Height); // 對角線偏移
            }
            return new Size(currentPos.X, currentPos.Y);
        }
    }
}

使用示例

<local:DiagonalPanel>
    <Button Content="First" />
    <Button Content="Second" />
    <Button Content="Third" />
</local:DiagonalPanel>

三個按鈕將沿對角線從左上向右下依次排開。

關鍵細節補充

  1. double.PositiveInfinity:Measure 時傳遞無限大,讓子元素不受父容器限制,獲得真實 DesiredSize。
  2. DesiredSize:Measure 完成後由系統自動設定的屬性,Arrange 階段直接使用。
  3. 回傳尺寸:MeasureOverride 回傳「理想需求」;ArrangeOverride 回傳「實際佔用」(通常等於 finalSize 或子元素佈局邊界)。
  4. 效能:避免在 Override 中創建大量臨時物件;複雜佈局考慮虛擬化 (VirtualizingPanel)。
  5. 邊界情況:availableSize 可能為 Infinity (如 ScrollViewer 內);finalSize 可能小於需求尺寸 (需裁剪/壓縮邏輯)。

進階延伸

  • WrapPanel 風格:Measure 累加行高,Arrange 遇邊界換行。
  • 流式佈局:結合 IScrollInfo 實現實體化虛擬化。
  • 動畫整合:Arrange 位置變更可配合 LayoutTransform 或 RenderTransform 產生過渡動畫。

掌握 Measure/Arrange 雙階段協商,即掌握了 WPF 佈局系統的靈魂,能構建任意想像的自定義容器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved