Udostępnij za pośrednictwem


Omówienie dekoracji

Zdobniki są specjalnym typem FrameworkElement, używanym do dostarczania wizualnych wskazówek użytkownikowi. Między innymi, Adorners mogą być używane do dodawania funkcjonalnych uchwytów do elementów lub dostarczania informacji o stanie kontroli.

O adoratorach

Adorner jest niestandardowym FrameworkElement powiązanym z UIElement. Elementy dekoracyjne są renderowane w AdornerLayer, czyli powierzchni renderowania, która jest zawsze nad ozdabianym elementem lub kolekcją ozdabianych elementów. Renderowanie adoratora jest niezależne od renderowania UIElement, z którym jest on powiązany. Element ozdobny jest zazwyczaj umieszczony w odniesieniu do elementu, do którego jest przypisany, przy użyciu standardowego źródła współrzędnych 2D znajdującego się w lewym górnym rogu elementu ozdobionego.

Typowe zastosowania zdobników to:

  • Dodawanie uchwytów funkcjonalnych do UIElement, które umożliwiają użytkownikowi manipulowanie elementem w jakiś sposób (zmiana rozmiaru, obracanie, położenie itp.).
  • Prześlij opinię wizualną, aby wskazać różne stany lub w odpowiedzi na różne zdarzenia.
  • Nakładanie dekoracji wizualnych na UIElement.
  • Wizualnie maskuj lub przesłaniaj część lub całość UIElement.

Windows Presentation Foundation (WPF) udostępnia podstawową platformę do ozdabiania elementów wizualnych. W poniższej tabeli wymieniono typy podstawowe używane podczas adorowania obiektów i ich przeznaczenie. Poniżej przedstawiono kilka przykładów użycia:

Klasa Opis
Adorner Abstrakcyjna klasa bazowa, z której dziedziczą wszystkie konkretne implementacje ozdobników.
AdornerLayer Klasa reprezentująca warstwę renderowania dla adornerów jednego lub więcej ozdabianych elementów.
AdornerDecorator Klasa, która umożliwia skojarzenie warstwy zdobienia z kolekcją elementów.

Implementowanie niestandardowego ozdobnika

Framework adorators zapewniany przez Windows Presentation Foundation (WPF) jest przeznaczony głównie do wspierania tworzenia niestandardowych adorators. Niestandardowy dekorator jest tworzony przez zaimplementowanie klasy, która dziedziczy po klasie abstrakcyjnej Adorner.

Notatka

Element nadrzędny Adorner jest AdornerLayer, który renderuje Adorner, a nie element, który jest ozdobiony.

W poniższym przykładzie przedstawiono klasę, która implementuje prosty moduł adoratora. Przykładowy ozdobnik po prostu ozdabia rogi UIElement za pomocą okręgów.

// 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

Na poniższej ilustracji przedstawiono aplikację SimpleCircleAdorner zastosowaną do TextBox:

Zrzut ekranu przedstawiający ozdobione pole tekstowe.

Zachowanie renderowania dla modułów adoratorów

Należy pamiętać, że zdobniki nie zawierają żadnych nieodłącznych zachowań renderowania; zapewnienie, że zdobnik się wyświetla, jest obowiązkiem osoby implementującej zdobnik. Typowym sposobem implementowania zachowania renderowania jest zastąpienie metody OnRender i użycie co najmniej jednego obiektu DrawingContext do renderowania wizualizacji modułu adoratora zgodnie z potrzebami (jak pokazano w powyższym przykładzie).

Notatka

Wszystkie elementy umieszczone w warstwie modułu adoratora są renderowane na podstawie pozostałych ustawionych stylów. Innymi słowy, ozdobniki są zawsze wizualnie na górze i nie można ich zastąpić przy użyciu kolejności warstw (z-order).

Zdarzenia i testowanie trafień

Dekoratory odbierają zdarzenia wejściowe tak samo jak każdy inny FrameworkElement. Ponieważ adorner zawsze ma wyższy z-rząd niż element, który ozdabia, adorner odbiera zdarzenia (takie jak Drop lub MouseMove), które mogą być przeznaczone dla leżącego poniżej ozdobionego elementu. Zdobnik może nasłuchiwać pewnych zdarzeń wejściowych i przekazywać je do bazowego elementu ozdobionego, powtórnie wywołując zdarzenie.

Aby umożliwić testowanie trafień elementów pod ozdobnikiem, ustaw właściwość testu trafienia IsHitTestVisible na wartość false na ozdobniku. Aby uzyskać więcej informacji na temat testowania trafień, zobacz hit testing in the Visual Layer.

Ozdabianie pojedynczego elementu interfejsu UI

Aby powiązać dekorator z określonym elementem UIElement, wykonaj następujące kroki:

  1. Wywołaj metodę statyczną GetAdornerLayer, aby uzyskać obiekt AdornerLayer dla UIElement, który ma zostać udekorowany. GetAdornerLayer przechodzi przez drzewo wizualne, zaczynając od określonego UIElement, i zwraca pierwszą odnalezioną warstwę dekoratora. (Jeśli nie znaleziono warstw nakładki dekoracyjnej, metoda zwraca null).

  2. Wywołaj metodę Add, aby powiązać adorner z docelowym UIElement.

Poniższy przykład wiąże element SimpleCircleAdorner (pokazany powyżej) z TextBox o nazwie myTextBox:

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

Notatka

Używanie języka XAML (Extensible Application Markup Language) do wiązania adornera z innym elementem nie jest obecnie obsługiwane.

Ozdabianie komponentów panelu

Aby powiązać moduł adoratora z elementami podrzędnym Panel, wykonaj następujące kroki:

  1. Wywołaj metodę staticGetAdornerLayer, aby znaleźć warstwę dekoratora dla elementu, aby ozdobić jego elementy podrzędne.

  2. Wylicz wszystkie elementy podrzędne elementu nadrzędnego i wywołaj metodę Add, aby powiązać adorator z każdym elementem podrzędnym.

Poniższy przykład wiąże element SimpleCircleAdorner (pokazany powyżej) z elementami podrzędnymi StackPanel o nazwie myStackPanel:

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

Zobacz też