Dela via


Använda DrawingVisual-objekt

Det här avsnittet innehåller en översikt över hur du använder DrawingVisual objekt i det visuella WPF-lagret.

DrawingVisual-objekt

DrawingVisual är en lätt ritningsklass som används för att återge former, bilder eller text. Den här klassen anses vara lätt eftersom den inte tillhandahåller layout eller händelsehantering, vilket förbättrar dess prestanda. Därför är ritningar idealiska för bakgrunder och ClipArt.

Värdcontainer för DrawingVisual

För att kunna använda DrawingVisual objekt måste du skapa en värdcontainer för objekten. Värdcontainerobjektet måste härledas från klassen FrameworkElement, vilket ger stöd för layout och händelsehantering som DrawingVisual-klassen saknar. Värdcontainerobjektet visar inga synliga egenskaper eftersom dess huvudsakliga syfte är att innehålla underordnade objekt. Egenskapen Visibility för värdcontainern måste dock vara inställd på Visible. annars visas inget av dess underordnade element.

När du skapar ett värdcontainerobjekt för visuella objekt måste du lagra referenser för visuella objekt i en VisualCollection. Använd metoden Add för att lägga till ett visuellt objekt i värdcontainern. I följande exempel skapas ett värdcontainerobjekt och tre visuella objekt läggs till i dess 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

Not

Det fullständiga kodexemplet som föregående kodexempel extraherades från finns i Hit Test Using DrawingVisuals Sample.

Skapa Ritningsvisualobjekt

När du skapar ett DrawingVisual objekt har det inget ritningsinnehåll. Du kan lägga till text, grafik eller bildinnehåll genom att hämta objektets DrawingContext och rita in det. En DrawingContext returneras genom att anropa metoden RenderOpen för ett DrawingVisual objekt.

Om du vill rita en rektangel i DrawingContextanvänder du metoden DrawRectangle för DrawingContext-objektet. Liknande metoder finns för att rita andra typer av innehåll. När du är klar med att rita innehåll i DrawingContextanropar du metoden Close för att stänga DrawingContext och spara innehållet.

I följande exempel skapas ett DrawingVisual objekt och en rektangel ritas in i dess 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

Skapa åsidosättningar för FrameworkElement-medlemmar

Värdcontainerobjektet ansvarar för att hantera sin samling av visuella objekt. Detta kräver att värdcontainern implementerar medlems åsidosättningar för den härledda FrameworkElement-klassen.

I följande lista beskrivs de två medlemmar som du måste åsidosätta:

  • GetVisualChild: Returnerar ett underordnat vid det angivna indexet från samlingen med underordnade element.

  • VisualChildrenCount: Hämtar antalet visuella barnelement i det här elementet.

I följande exempel implementeras åsidosättningar för de två FrameworkElement medlemmarna.


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

Erbjud stöd för träfftestning

Värdcontainerobjektet kan tillhandahålla händelsehantering även om det inte visar några synliga egenskaper, men dess Visibility-egenskap måste vara inställd på Visible. På så sätt kan du skapa en händelsehanteringsrutin för värdcontainern som kan fånga mushändelser, till exempel lanseringen av den vänstra musknappen. Händelsehanteringsrutinen kan sedan implementera träfftestning genom att anropa metoden HitTest. Metodens HitTestResultCallback-parameter refererar till en användardefinierad procedur som du kan använda för att fastställa den resulterande åtgärden för ett träfftest.

I följande exempel implementeras träfftestningsstöd för värdcontainerobjektet och dess underordnade objekt.

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

Se även