Condividi tramite


Utilizzo degli oggetti DrawingVisual

Aggiornamento: novembre 2007

In questo argomento vengono forniti cenni preliminari sull'utilizzo di oggetti DrawingVisual al livello visivo di WPF.

Di seguito sono elencate le diverse sezioni di questo argomento.

  • Oggetto DrawingVisual

  • Contenitore host di DrawingVisual

  • Creazione di oggetti DrawingVisual

  • Creazione di override per i membri FrameworkElement

  • Supporto per l'hit testing

  • Argomenti correlati

Oggetto DrawingVisual

DrawingVisual è una classe di disegno semplificata utilizzata per il rendering di forme, immagini o testo. Questa classe è considerata semplice perché non fornisce la gestione del layout o degli eventi, migliorando in tal modo le prestazioni. Per questo motivo, i disegni sono ideali per gli sfondi e per ClipArt.

Contenitore host di DrawingVisual

Per utilizzare oggetti DrawingVisual è necessario creare un contenitore host. L'oggetto contenitore host deve essere derivato dalla classe FrameworkElement che fornisce il layout e il supporto per la gestione di eventi che non sono supportati dalla classe DrawingVisual. Tramite l'oggetto contenitore host non vengono visualizzate proprietà visibili, poiché lo scopo principale di questo oggetto è quello di contenere oggetti figlio. Tuttavia, è necessario impostare la proprietà Visibility del contenitore host su Visible. In caso contrario, nessuno degli elementi figlio sarà visibile.

Quando si crea un oggetto contenitore host per gli oggetti visivi, è necessario archiviare i riferimenti agli oggetti visivi in VisualCollection. Utilizzare il metodo Add per aggiungere un oggetto visivo al contenitore host. Nell'esempio riportato di seguito, viene creato un oggetto contenitore host e tre oggetti visivi vengono aggiunti a VisualCollection.

// Create a host visual derived from the FrameworkElement class.
// This class provides layout, event handling, and container support for
// the child visual objects.
public class MyVisualHost : FrameworkElement
{
    // Create a collection of child visual objects.
    private VisualCollection _children;

    public MyVisualHost()
    {
        _children = new VisualCollection(this);
        _children.Add(CreateDrawingVisualRectangle());
        _children.Add(CreateDrawingVisualText());
        _children.Add(CreateDrawingVisualEllipses());

        // Add the event handler for MouseLeftButtonUp.
        this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
    }

Nota

Per l'esempio di codice completo dal quale è stato estratto l'esempio di codice precedente, vedere Esempio di hit test mediante DrawingVisual.

Creazione di oggetti DrawingVisual

Quando viene creato, un oggetto DrawingVisual non ha contenuto di disegno. È possibile aggiungere contenuto di testo, grafica o immagini recuperando DrawingContext per l'oggetto e disegnandovi. DrawingContext viene restituito chiamando il metodo RenderOpen di un oggetto DrawingVisual.

Per disegnare un rettangolo in DrawingContext utilizzare il metodo DrawRectangledell'oggetto DrawingContext. Sono disponibili metodi simili per disegnare altri tipi di contenuto. Al termine delle operazioni di disegno del contenuto in DrawingContext, chiamare il metodo Close per chiudere DrawingContext e mantenere il contenuto.

Nell'esempio riportato di seguito, viene creato un oggetto DrawingVisual e viene disegnato un rettangolo in DrawingContext.

// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle()
{
    DrawingVisual drawingVisual = new DrawingVisual();

    // Retrieve the DrawingContext in order to create new drawing content.
    DrawingContext drawingContext = drawingVisual.RenderOpen();

    // Create a rectangle and draw it in the DrawingContext.
    Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
    drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);

    // Persist the drawing content.
    drawingContext.Close();

    return drawingVisual;
}

Creazione di override per i membri FrameworkElement

L'oggetto contenitore host è responsabile della gestione dell'insieme di oggetti visivi. A tale scopo, è necessario che il contenitore host implementi l'override di membri per la classe FrameworkElement derivata.

Nell'elenco riportato di seguito vengono descritti due membri per i quali è necessario eseguire l'override:

  • GetVisualChild: restituisce un elemento figlio in corrispondenza dell'indice specificato dall'insieme di elementi figlio.

  • VisualChildrenCount: ottiene il numero di elementi figlio visivi all'interno di questo elemento.

Nell'esempio riportato di seguito, viene implementato l'override per i due membri FrameworkElement.

// Provide a required override for the VisualChildrenCount property.
protected override int VisualChildrenCount
{
    get { return _children.Count; }
}

// Provide a required override for the GetVisualChild method.
protected override Visual GetVisualChild(int index)
{
    if (index < 0 || index >= _children.Count)
    {
        throw new ArgumentOutOfRangeException();
    }

    return _children[index];
}

Supporto per l'hit testing

L'oggetto contenitore host può fornire la gestione degli eventi, anche se non visualizza alcuna proprietà visibile. Si noti tuttavia che la proprietà Visibility del contenitore deve essere impostata su Visible. Consente di creare una routine di gestione degli eventi per il contenitore host in grado di intercettare eventi del mouse, ad esempio il rilascio del pulsante sinistro del mouse. Tramite la routine di gestione degli eventi è quindi possibile implementare l'hit testing richiamando il metodo HitTest. Il parametro HitTestResultCallback del metodo fa riferimento a una procedura definita dall'utente che è possibile utilizzare per determinare l'azione risultante di un hit test.

Nell'esempio riportato di seguito, il supporto per l'hit testing viene implementato per l'oggetto contenitore host e i relativi elementi figlio.

// Capture the mouse event and hit test the coordinate point value against
// the child visual objects.
void MyVisualHost_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    // Retreive the coordinates of the mouse button event.
    System.Windows.Point pt = e.GetPosition((UIElement)sender);

    // Initiate the hit test by setting up a hit test result callback method.
    VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(myCallback), new PointHitTestParameters(pt));
}

// If a child visual object is hit, toggle its opacity to visually indicate a hit.
public HitTestResultBehavior myCallback(HitTestResult result)
{
    if (result.VisualHit.GetType() == typeof(DrawingVisual))
    {
        if (((DrawingVisual)result.VisualHit).Opacity == 1.0)
        {
            ((DrawingVisual)result.VisualHit).Opacity = 0.4;
        }
        else
        {
            ((DrawingVisual)result.VisualHit).Opacity = 1.0;
        }
    }

    // Stop the hit test enumeration of objects in the visual tree.
    return HitTestResultBehavior.Stop;
}

Vedere anche

Concetti

Cenni preliminari sul rendering della grafica in Windows Presentation Foundation

Hit testing a livello visivo

Riferimenti

DrawingVisual

HitTest