How to: Hit Test Geometry in a Visual

This example shows how to perform a hit test on a visual object that is composed of one or more Geometry objects.

Example

The following example shows how to retrieve the DrawingGroup from a visual object that uses the GetDrawing method. A hit test is then performed on the rendered content of each drawing in the DrawingGroup to determine which geometry was hit.

Note

In most cases, you would use the HitTest method to determine whether a point intersects any of the rendered content of a visual.

// Determine if a geometry within the visual was hit.
static public void HitTestGeometryInVisual(Visual visual, Point pt)
{
    // Retrieve the group of drawings for the visual.
    DrawingGroup drawingGroup = VisualTreeHelper.GetDrawing(visual);
    EnumDrawingGroup(drawingGroup, pt);
}

// Enumerate the drawings in the DrawingGroup.
static public void EnumDrawingGroup(DrawingGroup drawingGroup, Point pt)
{
    DrawingCollection drawingCollection = drawingGroup.Children;

    // Enumerate the drawings in the DrawingCollection.
    foreach (Drawing drawing in drawingCollection)
    {
        // If the drawing is a DrawingGroup, call the function recursively.
        if (drawing.GetType() == typeof(DrawingGroup))
        {
            EnumDrawingGroup((DrawingGroup)drawing, pt);
        }
        else if (drawing.GetType() == typeof(GeometryDrawing))
        {
            // Determine whether the hit test point falls within the geometry.
            if (((GeometryDrawing)drawing).Geometry.FillContains(pt))
            {
                // Perform action based on hit test on geometry.
            }
        }

    }
}
' Determine if a geometry within the visual was hit.
Public Shared Sub HitTestGeometryInVisual(ByVal visual As Visual, ByVal pt As Point)
	' Retrieve the group of drawings for the visual.
	Dim drawingGroup As DrawingGroup = VisualTreeHelper.GetDrawing(visual)
	EnumDrawingGroup(drawingGroup, pt)
End Sub

' Enumerate the drawings in the DrawingGroup.
Public Shared Sub EnumDrawingGroup(ByVal drawingGroup As DrawingGroup, ByVal pt As Point)
	Dim drawingCollection As DrawingCollection = drawingGroup.Children

	' Enumerate the drawings in the DrawingCollection.
	For Each drawing As Drawing In drawingCollection
		' If the drawing is a DrawingGroup, call the function recursively.
		If drawing.GetType() Is GetType(DrawingGroup) Then
			EnumDrawingGroup(CType(drawing, DrawingGroup), pt)
		ElseIf drawing.GetType() Is GetType(GeometryDrawing) Then
			' Determine whether the hit test point falls within the geometry.
			If (CType(drawing, GeometryDrawing)).Geometry.FillContains(pt) Then
				' Perform action based on hit test on geometry.
			End If
		End If

	Next drawing
End Sub

The FillContains method is an overloaded method that allows you to hit test by using a specified Point or Geometry. If a geometry is stroked, the stroke can extend outside the fill bounds. In which case, you may want to call StrokeContains in addition to FillContains.

You can also provide a ToleranceType that is used for the purposes of Bezier flattening.

Note

This sample does not take into account any transforms or clipping that may be applied to the geometry. In addition, this sample will not work with a styled control, since it does not have any drawings directly associated with it.

See Also

Hit Testing in the Visual Layer
Hit Test Using Geometry as a Parameter