Condividi tramite


Panoramica sugli Adorner

I decoratori sono un tipo speciale di FrameworkElement, usati per fornire segnali visivi all'utente. Tra gli altri usi, gli Adorner possono essere utilizzati per aggiungere maniglie funzionali agli elementi o fornire informazioni sullo stato di un controllo.

Informazioni sugli Adorner

Un Adorner è un FrameworkElement personalizzato associato a un UIElement. Il rendering degli adornatori viene realizzato in un AdornerLayer, ovvero una superficie di rendering sempre posizionata sopra l'elemento adornato o un insieme di elementi adornati. Il rendering di un addobbo è indipendente dal rendering del UIElement a cui l'addobbo è associato. Un decoratore è in genere posizionato rispetto all'elemento a cui è vincolato, utilizzando l'origine della coordinata 2D standard situata nell'angolo superiore sinistro dell'elemento decorato.

Le applicazioni comuni per gli strumenti decorativi includono:

  • Aggiunta di maniglie funzionali a un UIElement che consentono a un utente di modificare l'elemento in vari modi (ridimensionare, ruotare, riposizionare e così via).
  • Fornire feedback visivo per indicare vari stati o in risposta a vari eventi.
  • Sovrapporre decorazioni visive su un UIElement.
  • Mascherare visivamente o sostituire una parte o tutto di UIElement.

Windows Presentation Foundation (WPF) fornisce un framework di base per adornare gli elementi visivi. Nella tabella seguente sono elencati i tipi principali usati per adornare gli oggetti e il relativo scopo. Di seguito sono riportati diversi esempi di utilizzo:

Classe Descrizione
Adorner Classe base astratta da cui ereditano tutte le implementazioni concrete di 'adorner'.
AdornerLayer Classe che rappresenta uno strato di rendering per i decori di uno o più elementi adornati.
AdornerDecorator La classe che consente l'associazione di un livello decorativo a una raccolta di elementi.

Implementazione di un adorner personalizzato

Il framework degli strumenti decorativi fornito da Windows Presentation Foundation (WPF) è destinato principalmente a supportare la creazione di strumenti decorativi personalizzati. Uno strumento decorativo personalizzato viene creato implementando una classe che eredita dalla classe Adorner astratta.

Nota

L'elemento padre di un Adorner è il AdornerLayer che renderizza il Adorner, non l'elemento che viene adornato.

Nell'esempio seguente viene illustrata una classe che implementa un semplice strumento decorativo. Lo strumento decorativo di esempio adorna semplicemente gli angoli di un UIElement con cerchi.

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

L'immagine seguente mostra come l'oggetto SimpleCircleAdorner è applicato a un TextBox:

Screenshot che mostra una casella di testo adornata.

Comportamento di rendering per gli strumenti decorativi

È importante notare che gli strumenti decorativi non includono alcun comportamento di rendering intrinseco; garantire che un strumento decorativo esegua il rendering è responsabilità dell'implementatore dello strumento decorativo. Un modo comune per implementare il comportamento di rendering consiste nell'eseguire l'override del metodo OnRender e usare uno o più oggetti DrawingContext per eseguire il rendering degli elementi visivi dell'adorner secondo necessità (come illustrato nell'esempio precedente).

Nota

Qualsiasi elemento posizionato nel livello decorativo viene renderizzato sopra il resto degli stili impostati. In altre parole, gli adorner sono sempre visivamente in cima e non possono essere sovrascritti usando l'ordine z.

Eventi e test di impatto

Gli adornatori ricevono eventi di input come qualsiasi altro FrameworkElement. Poiché uno strumento decorativo ha sempre un ordine z superiore rispetto all'elemento che adorna, lo strumento decorativo riceve gli eventi di input (ad esempio Drop o MouseMove) che possono essere destinati all'elemento adornato sottostante. Un adorner può ascoltare determinati eventi di input e trasmetterli all'elemento adornato sottostante, generando nuovamente l'evento.

Per abilitare l'hit test pass-through degli elementi sotto un adorner, impostare la proprietà di hit test IsHitTestVisible su false sull'adorner. Per altre informazioni sull'hit testing, vedere Hit Testing in Visual Layer.

Adornare un singolo UIElement

Per associare un decoratore a un particolare UIElement, seguire questa procedura:

  1. Chiamare il metodo statico GetAdornerLayer per ottenere un oggetto AdornerLayer da adornare il UIElement. GetAdornerLayer risale l'albero visivo, iniziando dal UIElementspecificato, e restituisce il primo livello adorner che trova. Se non viene trovato alcun livello decorativo, il metodo restituisce null.

  2. Chiamare il metodo Add per associare lo strumento decorativo al UIElementdi destinazione.

L'esempio seguente associa SimpleCircleAdorner (illustrato sopra) a un TextBox chiamato myTextBox:

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

Nota

L'uso del linguaggio XAML (Extensible Application Markup Language) per associare uno strumento decorativo a un altro elemento non è attualmente supportato.

Adornare gli elementi figli di un pannello

Per associare un decoratore ai figli di un Panel, seguire questa procedura:

  1. Chiamare il metodo staticGetAdornerLayer per trovare uno strato di ornamento per l'elemento i cui figli devono essere adornati.

  2. Enumerare gli elementi figlio dell'elemento padre e chiamare il metodo Add per associare un adorner a ogni elemento figlio.

L'esempio seguente associa SimpleCircleAdorner (illustrato sopra) agli elementi figlio di un StackPanel denominato 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

Vedere anche