Reply to thread

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

visuals.Add(bodyVisual)

visuals.Add(eyesVisual)

visuals.Add(mouthVisual)

For Each v In visuals

AddVisualChild(v)

AddLogicalChild(v)

Next

End Sub

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

Protected Shadows ReadOnly Property VisualChildrenCount() As Integer

Get

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

MyBase.OnMouseLeftButtonDown(e)

'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.



More...


View All Our Microsft Related Feeds


Back
Top