如何:对 Visual 中的几何图形进行命中测试

此示例演示如何对由一个或多个 Geometry 对象组成的视觉对象执行命中测试。

示例

以下示例显示如何从使用 GetDrawing 方法的视觉对象中检索 DrawingGroup。 随后,此示例对 DrawingGroup 中每个绘图所呈现的内容执行命中测试,以确定命中了哪个几何图形。

注意

在大多数情况下,将使用 HitTest 方法来确定点是否与视觉对象的任何呈现内容有交集。

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

FillContains 方法是一种重载方法,支持通过使用指定的 PointGeometry 命中测试。 绘制几何图形时,笔画可以延伸到填充边界之外。 在此情况下,除了 FillContains,你可能还需要调用 StrokeContains

还可以提供一个 ToleranceType 以用于贝塞尔拉平操作。

注意

此示例并未考虑可能应用到几何图形中的任何变形或剪裁。 此外,此示例不会使用已设置样式的控件,因为这种控件没有与它直接关联的绘图。

另请参阅