Tech Off Post

Single Post Permalink

View Thread: I always get a black backgraound with DrawingContext in WPF
  • User profile image

    Whew! Thanks dex. Actually I wasn't going to do anything drastic.

     I put the background on first to give it the lowest Z order and then pass over it in the hit testing. Here is the complete code for the sake of public documentation; it draw some scary ghost:

    Imports System.Windows
    Imports System.Windows.Media
    Imports System.Collections.Generic
    Imports System.Windows.Input
    Namespace WindowHostingVisual
       Class Application
          <STAThread()> _
          Public Shared Sub Main()
             Dim whv As New WindowHostingVisual.WindowHostingVisual()
          End Sub
       End Class
       Namespace WindowHostingVisual
          Public Class WindowHostingVisual
             Inherits Window
             Private visuals As New List(Of Visual)()
             Public Sub New()
                Title = "Hosting DrawingVisuals"
                Width = 400
                Height = 400
                Background = Brushes.Aquamarine
                Me.WindowStartupLocation = Windows.WindowStartupLocation.CenterScreen
                Dim bodyVisual As New DrawingVisual()
                Dim eyesVisual As New DrawingVisual()
                Dim mouthVisual As New DrawingVisual()
                Dim visBackground As New DrawingVisual
                Using dc As DrawingContext = bodyVisual.RenderOpen()
                   dc.DrawGeometry(Brushes.Blue, Nothing, Geometry.Parse("M 240,250 C 200,375 200,250 175,200 C 100,400 100,250 100,200 C 0,350 0,250 30,130 C 75,0 100,0 150,0 C 200,0 250,0 250,150 Z"))
                End Using
                Using dc As DrawingContext = eyesVisual.RenderOpen()
                   dc.DrawEllipse(Brushes.Black, New Pen(Brushes.White, 10), New Point(95, 95), 15, 15)
                   dc.DrawEllipse(Brushes.Black, New Pen(Brushes.White, 10), New Point(170, 105), 15, 15)
                End Using
                Using dc As DrawingContext = mouthVisual.RenderOpen()
                   Dim p As New Pen(Brushes.Black, 10)
                   p.StartLineCap = PenLineCap.Round
                   p.EndLineCap = PenLineCap.Round
                   dc.DrawLine(p, New Point(75, 160), New Point(175, 150))
                End Using
                Using dc As DrawingContext = visBackground.RenderOpen
                   dc.DrawRectangle(Background, Nothing, New Rect(0, 0, Width, Height))
                End Using
                ' Bookkeeping:
                For Each v As Visual In visuals
             End Sub
             ' The two necessary overrides, implemented for the single Visual:
             Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
                   Return visuals.Count
                End Get
             End Property
             Protected Overrides Function GetVisualChild(index As Integer) As Visual
                If index < 0 OrElse index >= visuals.Count Then
                   Throw New ArgumentOutOfRangeException("index")
                End If
                Return visuals(index)
             End Function
             Protected Overrides Sub OnMouseLeftButtonDown(e As MouseButtonEventArgs)
                ' Rotate object clicked on.
                ' Retrieve the mouse pointer location relative to the Window
                Dim location As Point = e.GetPosition(Me)
                ' Perform visual hit testing
                Dim result As HitTestResult = VisualTreeHelper.HitTest(Me, location)
                ' If we hit any DrawingVisual, rotate it
                If result.VisualHit.[GetType]() = GetType(DrawingVisual) Then
                   Dim dv As DrawingVisual = TryCast(result.VisualHit, DrawingVisual)
                   ' Don't rotate background.
                   If dv.Equals(visuals.Item(0)) Then
                      Exit Sub
                   End If
                   If dv.Transform Is Nothing Then
                      dv.Transform = New RotateTransform()
                   End If
                   TryCast(dv.Transform, RotateTransform).Angle += 1
                End If
             End Sub
          End Class
       End Namespace
    End Namespace

    I think my real question is what I am really drawing on. It seems to not be the window object. I don't know what the DrawingContext actually is and where it fits in. I do now know the drawn objects can be accessed through LogicalTreeHelper and VisualTreeHelper. To quote from WPF Unleashed: "However, you can easily traverse both the logical and visual trees using the somewhat
    symmetrical System.Windows.LogicalTreeHelper and System.Windows.Media.
    VisualTreeHelper classes."