Utilisation d’objets DrawingVisual

Cette rubrique fournit une vue d’ensemble de l’utilisation DrawingVisual d’objets dans la couche visuelle WPF.

Objet DrawingVisual

Il DrawingVisual s’agit d’une classe de dessin légère utilisée pour afficher des formes, des images ou du texte. Cette classe est dite légère, car elle n’assure pas la gestion des dispositions ni des événements, ce qui améliore ses performances. C’est pour cette raison que les dessins sont idéaux pour les arrière-plans et les images clipart.

Conteneur hôte DrawingVisual

Pour utiliser des DrawingVisual objets, vous devez créer un conteneur hôte pour les objets. L’objet conteneur hôte doit dériver de la FrameworkElement classe, qui fournit la prise en charge de la disposition et de la gestion des événements que la DrawingVisual classe manque. L’objet de type conteneur hôte n’affiche pas de propriétés visibles, dans la mesure où son but principal est de contenir des objets enfants. Toutefois, la Visibility propriété du conteneur hôte doit être définie Visiblesur ; sinon, aucun de ses éléments enfants n’est visible.

Lorsque vous créez un objet conteneur hôte pour les objets visuels, vous devez stocker les références d’objets visuels dans un VisualCollection. Utilisez la Add méthode pour ajouter un objet visuel au conteneur hôte. Dans l’exemple suivant, un objet conteneur hôte est créé et trois objets visuels sont ajoutés à son 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);
    }
' 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
    Inherits FrameworkElement
    ' Create a collection of child visual objects.
    Private _children As VisualCollection

    Public Sub New()
        _children = New VisualCollection(Me)
        _children.Add(CreateDrawingVisualRectangle())
        _children.Add(CreateDrawingVisualText())
        _children.Add(CreateDrawingVisualEllipses())

        ' Add the event handler for MouseLeftButtonUp.
        AddHandler MouseLeftButtonUp, AddressOf MyVisualHost_MouseLeftButtonUp
    End Sub

Remarque

Pour consulter l’intégralité de l’exemple de code duquel l’exemple de code précédent a été extrait, référez-vous à la section Hit Test Using DrawingVisuals Sample (Test de positionnement à l’aide d’exemples de DrawingVisuals).

Création d'objets DrawingVisual

Lorsque vous créez un DrawingVisual objet, il n’a pas de contenu de dessin. Vous pouvez ajouter du texte, des graphiques ou du contenu d’image en récupérant l’objet DrawingContext et en le dessinant. A DrawingContext est retourné en appelant la RenderOpen méthode d’un DrawingVisual objet.

Pour dessiner un rectangle dans l’objet DrawingContext, utilisez la DrawRectangle méthode de l’objet DrawingContext . Il existe des méthodes similaires pour dessiner d’autres types de contenu. Lorsque vous avez terminé de dessiner du contenu dans le DrawingContextfichier , appelez la Close méthode pour fermer et DrawingContext conserver le contenu.

Dans l’exemple suivant, un DrawingVisual objet est créé et un rectangle est dessiné dans son 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;
}
' Create a DrawingVisual that contains a rectangle.
Private Function CreateDrawingVisualRectangle() As DrawingVisual
    Dim drawingVisual As New DrawingVisual()

    ' Retrieve the DrawingContext in order to create new drawing content.
    Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()

    ' Create a rectangle and draw it in the DrawingContext.
    Dim rect As New Rect(New Point(160, 100), New Size(320, 80))
    drawingContext.DrawRectangle(Brushes.LightBlue, CType(Nothing, Pen), rect)

    ' Persist the drawing content.
    drawingContext.Close()

    Return drawingVisual
End Function

Création de remplacements pour les membres FrameworkElement

L’objet de type conteneur hôte est chargé de gérer sa collection d’objets visuels. Cela nécessite que le conteneur hôte implémente les remplacements de membre pour la classe dérivée FrameworkElement .

La liste suivante décrit les deux membres que vous devez substituer :

  • GetVisualChild: retourne un enfant à l’index spécifié à partir de la collection d’éléments enfants.

  • VisualChildrenCount: obtient le nombre d’éléments enfants visuels dans cet élément.

Dans l’exemple suivant, les remplacements pour les deux FrameworkElement membres sont implémentés.


// 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];
}


' Provide a required override for the VisualChildrenCount property.
Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
    Get
        Return _children.Count
    End Get
End Property

' Provide a required override for the GetVisualChild method.
Protected Overrides Function GetVisualChild(ByVal index As Integer) As Visual
    If index < 0 OrElse index >= _children.Count Then
        Throw New ArgumentOutOfRangeException()
    End If

    Return _children(index)
End Function

Prise en charge du test de positionnement

L’objet conteneur hôte peut fournir la gestion des événements même s’il n’affiche pas de propriétés visibles. Toutefois, sa Visibility propriété doit être définie sur Visible. Cela vous permet de créer une routine de gestion des événements pour le conteneur hôte, capable de détecter les événements de la souris, tels que le relâchement du bouton gauche de la souris. La routine de gestion des événements peut ensuite implémenter des tests de positionnement en appelant la HitTest méthode. Le paramètre de HitTestResultCallback la méthode fait référence à une procédure définie par l’utilisateur que vous pouvez utiliser pour déterminer l’action résultante d’un test de positionnement.

Dans l’exemple suivant, la prise en charge du test de positionnement est implémentée pour l’objet de type conteneur hôte et ses enfants.

// 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)
{
    // Retrieve 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;
}
' Capture the mouse event and hit test the coordinate point value against
' the child visual objects.
Private Sub MyVisualHost_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
    ' Retrieve the coordinates of the mouse button event.
    Dim pt As Point = e.GetPosition(CType(sender, UIElement))

    ' Initiate the hit test by setting up a hit test result callback method.
    VisualTreeHelper.HitTest(Me, Nothing, New HitTestResultCallback(AddressOf myCallback), New PointHitTestParameters(pt))
End Sub

' If a child visual object is hit, toggle its opacity to visually indicate a hit.
Public Function myCallback(ByVal result As HitTestResult) As HitTestResultBehavior
    If result.VisualHit.GetType() Is GetType(DrawingVisual) Then
        If (CType(result.VisualHit, DrawingVisual)).Opacity = 1.0 Then
            CType(result.VisualHit, DrawingVisual).Opacity = 0.4
        Else
            CType(result.VisualHit, DrawingVisual).Opacity = 1.0
        End If
    End If

    ' Stop the hit test enumeration of objects in the visual tree.
    Return HitTestResultBehavior.Stop
End Function

Voir aussi