Utilisation d'objets DrawingVisual

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

Cette rubrique contient les sections suivantes.

  • Objet DrawingVisual

  • Conteneur hôte DrawingVisual

  • Création d'objets DrawingVisual

  • Création de substitutions pour des membres FrameworkElement

  • Fourniture de la prise en charge des tests de positionnement

  • Rubriques connexes

Objet DrawingVisual

DrawingVisual est une classe de dessin légère utilisée pour le rendu des formes, des images ou du texte. Cette classe est considérée comme légère parce qu'elle ne fournit pas la disposition ou la gestion d'événements, ce qui améliore ses performances. Pour cette raison, les dessins sont idéaux pour les arrière-plans et les images clipart.

Conteneur hôte DrawingVisual

Pour pouvoir utiliser des objets DrawingVisual, vous devez créer un conteneur hôte pour les objets. L'objet conteneur hôte doit être dérivé de la classe FrameworkElement, qui fournit la disposition et la gestion des événements que la classe DrawingVisual ne prend pas en charge. L'objet conteneur hôte n'affiche aucune propriété visible, car il est principalement conçu pour contenir des objets enfants. Toutefois, la propriété Visibility du conteneur hôte doit avoir la valeur Visible, sinon, aucun de ses éléments enfants n'est visible.

Lorsque vous créez un objet conteneur hôte pour des objets visuels, vous devez stocker les références des objets visuels dans un VisualCollection. Utilisez la méthode Add 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 à 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
        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
// 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);
    }
RemarqueRemarque

Pour obtenir l'exemple de code complet duquel l'exemple de code précédent a été extrait, consultez Test de positionnement à l'aide de DrawingVisuals, exemple.

Création d'objets DrawingVisual

Lorsque vous créez un objet DrawingVisual, celui-ci ne comporte aucun contenu de dessin. Vous pouvez ajouter du texte, des graphiques ou du contenu d'image en récupérant le DrawingContext de l'objet et en dessinant dedans. Un DrawingContext est retourné en appelant la méthode RenderOpen d'un objet DrawingVisual.

Pour dessiner un rectangle dans DrawingContext, utilisez la méthode DrawRectangle de l'objet DrawingContext. Il existe des méthodes similaires permettant de dessiner d'autres types de contenu. Après avoir dessiné le contenu dans DrawingContext, appelez la méthode Close pour fermer DrawingContext et conserver le contenu.

Dans l'exemple suivant, un objet DrawingVisual est créé et un rectangle est dessiné dans DrawingContext.

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

Création de substitutions pour des membres FrameworkElement

L'objet conteneur hôte est chargé de gérer sa collection d'objets visuels. Pour ce faire, le conteneur hôte doit implémenter des substitutions de membres pour la classe FrameworkElement dérivée.

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

  • GetVisualChild : retourne un enfant au niveau de 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, des substitutions pour les deux membres FrameworkElement sont implémentées.


        ' 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


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

Fourniture de la prise en charge des tests de positionnement

L'objet conteneur hôte peut fournir la gestion des événements même s'il n'affiche aucune propriété visible. Toutefois, sa propriété Visibility doit avoir la valeur Visible. Vous pouvez ainsi créer une routine de gestion des événements pour le conteneur hôte qui peut intercepter les événements de souris, comme le relâchement du bouton gauche de la souris. La routine de gestion des événements peut ensuite implémenter les tests de positionnement en appelant la méthode HitTest. Le paramètre HitTestResultCallback de 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 des tests de positionnement est implémentée pour l'objet conteneur hôte et ses enfants.

        ' 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)
            ' Retreive 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
// 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;
}

Voir aussi

Référence

DrawingVisual

HitTest

Concepts

Vue d'ensemble du rendu graphique de WPF

Test de positionnement dans la couche visuelle