2

我有一个 WPFParentUserControl和一些ChildUserControlA ChildUserControlB等等(还有 WPF 控件)

s 是控件,其中ChildUserControl包含一些其他基本元素(文本框、标签等)

在主窗体的状态栏中,我需要显示当前鼠标悬停的ChildUserControl的名称。

因此,在ParentUserControl的 MouseMove 中,我获得了一个对象myElement = Mouse.DirectlyOver,因为我需要最上面的ChildUserControl,但我获得了一个 'System.Windows.Controls.TextBlock'(ChildUserControl 的一部分)......

如何解决?

当我将鼠标悬停在 MyChildControl 上时,我需要检测到 MyChildControl,而不是它的子元素。

按照这个顺序,我在 MyChildControl 上使用了以下内容:

Protected Overrides Function HitTestCore(
                    hitTestParameters As PointHitTestParameters) As HitTestResult

    Return New PointHitTestResult(Me, hitTestParameters.HitPoint)
End Function

但无论如何我有时会得到文本块,有时会得到 ChildUserControl ......

4

2 回答 2

3

您需要实施Hit-Testing。因此,如果您想获取区域内的所有元素,您可以使用HitTestResultCallback。一个例子:

Dim Elements As New List(Of FrameworkElement)


Public Function GetVisuals(ByVal Region As Geometry) As List(Of FrameworkElement)

    If Region Is Nothing Then Return Nothing

    Dim Parameters As New GeometryHitTestParameters(Region)
    Elements.Clear()

    Dim Callback As New HitTestResultCallback(AddressOf Me.HitTestCallBack)
    VisualTreeHelper.HitTest(Me.ParentUserControl, Nothing, Callback, Parameters)

    Return Me.Elements

End Function

Private Function HitTestCallBack(ByVal Result As HitTestResult) As HitTestResultBehavior

    If Result IsNot Nothing Then

        Dim GeometryRes As GeometryHitTestResult = CType(Result, GeometryHitTestResult)
        Dim Element As FrameworkElement = TryCast(Result.VisualHit, FrameworkElement)

        If Element IsNot Nothing AndAlso GeometryRes.IntersectionDetail = IntersectionDetail.FullyContains Then
            Me.Elements.Add(Element)
        End If

    End If

    Return HitTestResultBehavior.Continue

End Function

这样,Elements 列表包含了GeometryHitTestResult.IntersectionDetail指定的所有元素,如果您想(例如)知道鼠标位置(MouseDown 事件)下的元素,只需这样做:

Dim Region As New RectangleGeometry(New Rect(e.GetPosition(Me.MyGrid), New Size(1, 1)))
Dim Elements As List(Of FrameworkElement) = Me.GetVisuals(Region)

这就是我在评论中的意思:

Public Class DrawingCanvas
Inherits Panel

Public Function GetVisuals(ByVal Region As Geometry) As List(Of DrawingVisual)
End Function

Private Function HitTestCallBack(ByVal Result As HitTestResult) As HitTestResultBehavior
End Function

End Class
于 2012-04-17T16:43:06.887 回答
1

另一个答案可能是这样的 - 定义您关心的对象的确切类型并处理视觉树,直到找到它们:

Private myTypes As New List(Of Type)()
Public Sub New()
    InitializeComponent()
    myTypes.Add(GetType(ComboBox))
    myTypes.Add(GetType(CheckBox))
    myTypes.Add(GetType(RadioButton))
    myTypes.Add(GetType(TabControl))
    myTypes.Add(GetType(Button))
    myTypes.Add(GetType(Label))
    myTypes.Add(GetType(GroupBox))
    myTypes.Add(GetType(Window))
End Sub

Private Sub Window_MouseMove(sender As Object, e As MouseEventArgs)
    Dim x As DependencyObject = _
      DirectCast(e.MouseDevice.DirectlyOver, DependencyObject)
    Dim t As Type = x.GetType
    While Not myTypes.Contains(t)
         x = VisualTreeHelper.GetParent(x)
         If x Is Nothing Then Exit While
         t = x.GetType
    End While

    If x IsNot Nothing Then
          Console.WriteLine(x.ToString())
    Else
          Console.WriteLine("Nothing")
    End If
End Sub
于 2012-04-17T16:53:44.650 回答