共用方式為


裝飾項概觀

裝飾項是一種特殊的 FrameworkElement,可用來提供視覺提示給使用者。 除了其他用法,裝飾項還可用來將功能控點加入項目,或提供控制項的狀態資訊。

關於裝飾項

Adorner 是繫結至的 UIElement 自訂 FrameworkElement。 裝飾項會轉譯在 AdornerLayer,這是一律位於裝飾元素或裝飾元素集合最上層的轉譯介面。 裝飾項轉譯與裝飾項繫結至的 UIElement 轉譯無關。 裝飾項的位置通常會相對於其所繫結的目標項目,並使用標準 2D 座標,原點位於裝飾項目的左上角。

裝飾項的常見應用包括︰

  • 新增功能控制代碼至 UIElement,這些控制代碼可讓使用者以某種方式操作項目 (調整大小、旋轉、重新置放等等)。
  • 提供視覺化回應以表示各種狀態,或回應各種事件。
  • UIElement 上重疊視覺裝飾。
  • 以視覺方式遮罩或覆寫部分或全部 UIElement

Windows Presentation Foundation (WPF) 提供裝飾視覺效果元素的基本架構。 下表列出在裝飾物件時所使用的主要類型,及其用途。 以下是幾個使用方式的範例:

類別 描述
Adorner 抽象基底類別,所有具體裝飾項實作都繼承自該類別。
AdornerLayer 代表一個或多個裝飾項目的裝飾項轉譯層的類別。
AdornerDecorator 可讓裝飾項層與項目集合相關聯的類別。

實作自訂裝飾項

Windows Presentation Foundation (WPF) 所提供的裝飾項架構主要是為了支援建立自訂裝飾項。 藉由實作繼承自抽象 Adorner 類別的類別,建立自訂 Adorner。

注意

Adorner 的父系是轉譯 AdornerAdornerLayer,而不是裝飾的元素。

下列範例顯示一個實作簡單裝飾項的類別。 裝飾項範例只會用圓形來裝飾 UIElement 的角落。

// Adorners must subclass the abstract base class Adorner.
public class SimpleCircleAdorner : Adorner
{
  // Be sure to call the base class constructor.
  public SimpleCircleAdorner(UIElement adornedElement)
    : base(adornedElement)
  {
  }

  // A common way to implement an adorner's rendering behavior is to override the OnRender
  // method, which is called by the layout system as part of a rendering pass.
  protected override void OnRender(DrawingContext drawingContext)
  {
    Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);

    // Some arbitrary drawing implements.
    SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
    renderBrush.Opacity = 0.2;
    Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
    double renderRadius = 5.0;

    // Draw a circle at each corner.
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
  }
}
Public Class SimpleCircleAdorner
    Inherits Adorner
    Sub New(ByVal adornedElement As UIElement)
        MyBase.New(adornedElement)
    End Sub

    Protected Overrides Sub OnRender(ByVal drawingContext As System.Windows.Media.DrawingContext)
        MyBase.OnRender(drawingContext)
        Dim adornedElementRect As New Rect(AdornedElement.DesiredSize)
        Dim renderBrush As New SolidColorBrush(Colors.Green)
        renderBrush.Opacity = 0.2
        Dim renderPen As New Pen(New SolidColorBrush(Colors.Navy), 1.5)
        Dim renderRadius As Double
        renderRadius = 5.0

        'Draw a circle at each corner.
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius)
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius)
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius)
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius)
    End Sub
End Class

下圖顯示套用至 TextBox 的 SimpleCircleAdorner:

顯示裝飾文字輸入框的螢幕擷取畫面。

裝飾項的轉譯行為

請務必注意,裝飾項並不包括任何繼承的轉譯行為。裝飾項實作者必須負責確定裝飾項轉譯器。 實作轉譯行為的常見方式是覆寫 OnRender 方法,並使用一或多個 DrawingContext 物件視需要轉譯 Adorner 的視覺效果 (如上述範例所示)。

注意

放在裝飾項圖層中的任何項目會轉譯在您已設定的其餘任何樣式之上。 換句話說,裝飾項永遠是以視覺化方式在最上面,而且無法使用疊置順序覆寫。

事件和點擊測試

裝飾項會如同任何其他 FrameworkElement 一樣接收輸入事件。 因為裝飾項的疊置順序一律會較其裝飾的元素高,所以裝飾項會接收輸入事件 (例如 DropMouseMove),而這些事件可能是要給基礎的被裝飾元素。 裝飾項可以接聽特定的輸入事件,並藉由重新引發事件將它們傳送到基礎的被裝飾項目。

若要啟用裝飾項以下的項目傳遞式點擊測試,請在裝飾項上將點擊測試 IsHitTestVisible 屬性設為 false。 如需關於點擊測試的詳細資訊,請參閱視覺分層中的點擊測試

裝飾單一的 UIElement

若要將 Adorner 繫結至特定 UIElement,請遵循下列步驟:

  1. 呼叫靜態方法 GetAdornerLayer,以取得要 UIElement 裝飾的 AdornerLayer 物件。 GetAdornerLayer 會逐步執行可視化樹狀結構,從指定的 UIElement 開始,並傳回其找到的第一個裝飾圖層。 (如果找不到任何裝飾項圖層,方法會傳回 null。)

  2. 呼叫 Add 方法,將裝 Adorner 繫結至目標 UIElement

下列範例會將 SimpleCircleAdorner (如上所示) 繫結到名為 myTextBoxTextBox

myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SimpleCircleAdorner(myTextBox));
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox)
myAdornerLayer.Add(New SimpleCircleAdorner(myTextBox))

注意

目前不支援使用 Extensible Application Markup Language (XAML) 將 Adorner 繫結至另一個元素。

裝飾 Panel 的子系

若要將裝飾項繫結至 Panel 的子系,請遵循下列步驟:

  1. 呼叫 static 方法 GetAdornerLayer,以尋找要裝飾其子系之元素的裝飾項圖層。

  2. 透過父元素的子系列舉並呼叫 Add 方法,將裝飾項繫結至每個子元素。

下列範例將 SimpleCircleAdorner (如上所示) 繫結至名為 myStackPanelStackPanel 的子系:

foreach (UIElement toAdorn in myStackPanel.Children)
  myAdornerLayer.Add(new SimpleCircleAdorner(toAdorn));
For Each toAdorn As UIElement In myStackPanel.Children
    myAdornerLayer.Add(New SimpleCircleAdorner(toAdorn))
Next

另請參閱