Tech Off Thread

4 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

WPF GetVisualChild Bug with VB.NET

Back to Forum: Tech Off
  • User profile image

    I'm trying to work through the WPF Unleashed book by Adam Nathan, as I'm going I'm working through with VB.NET rather than the C# samples in the book just to see how it translates.

    I have reached chapter 11 and the section about Hit Testing with Multiple Visuals.

    The code in the book draws a ghost with mouth, eyes, and body all of which rotate seperately when clicked. The c# sample works fine from the authors site but when i translate it to VB.NET it doesn't work, after a bit of debugging the GetVisualChild overridden method only ever gets called with a value of 0 passed in while when running the c# sample it gets called with a value for each item (0,1,2) in the collection.

    The code below is, as far as I can see, the exact equivalent of the C# in the book but it only draws the ghost's body (or if I change the order of the items in the 'visuals' list it is always the first item) which makes sense if GetVisualChild only gets called with a val of 0.

    Public Class WPFHostDrawing2

    Inherits Window

    Dim visuals As New List(Of Visual)

    Sub New()

    Title = "Hosting DrawingVisuals"

    Width = 300

    Height = 350

    Dim bodyVisual As New DrawingVisual()

    Dim eyesVisual As New DrawingVisual()

    Dim mouthVisual As New DrawingVisual()

    Using dc As DrawingContext = bodyVisual.RenderOpen()

    'The body

    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()

    'left eye

    dc.DrawEllipse(Brushes.Black, New Pen(Brushes.White, 10), New Point(95, 95), 15, 15)

    'right eye

    dc.DrawEllipse(Brushes.Black, New Pen(Brushes.White, 10), New Point(170, 105), 15, 15)

    End Using

    Using dc As DrawingContext = mouthVisual.RenderOpen()

    'the mouth

    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




    For Each v In visuals




    End Sub

    ' The two necessary overrides, implemented for the single Visual:

    Protected Shadows ReadOnly Property VisualChildrenCount() As Integer


    Return visuals.Count

    End Get

    End Property

    Protected Overrides Function GetVisualChild(ByVal index As Integer) As Visual

    If index < 0 OrElse index >= visuals.Count Then

    Throw New ArgumentOutOfRangeException("index")

    End If

    Return visuals(index)

    End Function

    Private Sub WPFHostDrawing_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonDown


    'Reteive the mouse pointer location relative to the Window

    Dim location As Point = e.GetPosition(Me)

    'Perform visual hit testing for the entire Window

    Dim result As HitTestResult = VisualTreeHelper.HitTest(Me, location)

    'If we hit any DrawingVisual, rotate it

    If result.VisualHit.GetType() Is GetType(DrawingVisual) Then

    Dim dv As DrawingVisual = result.VisualHit

    If dv.Transform Is Nothing Then

    dv.Transform = New RotateTransform()

    End If

    CType(dv.Transform, RotateTransform).Angle = CType(dv.Transform, RotateTransform).Angle + 1

    End If

    End Sub

    End Class

    Can anyone see an error, or just tell me they get the same and it must be a bug, it is driving my slightly crazy. Thanks.

  • User profile image

    I tried it and get the same problem.

  • User profile image

    I am by no means a VB.NET programmer, so I sent this thread to our internal discussion group, and I get the answer from there:

    MSFT Employee wrote:

    Protected Shadows ReadOnly Property VisualChildrenCount() As Integer


          Return visuals.Count

        End Get

      End Property



    Should be


      Protected Overrides ReadOnly Property VisualChildrenCount() As Integer


          Return visuals.Count

        End Get

      End Property


    When called on a parent class the Shadows property implementation is not called.  Rather the base class property is called, which returns 1.


    I should be able to figure this out myself, because In C#, I know what "Shadows" actually means:(

  • User profile image

    Thank you, I should have caught that myself. Was always more likely to be a bug in my brain than in the framework Smiley.

    Thanks again.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.