0

这是一个 WPF 应用程序。

我试图直接在鼠标下方进行控制,事实证明这是一种令人惊讶的痛苦。

Mouse.DirectlyOver、InputHitTest 和 VisualTreeHelper.HitTest 都引用了 VISUAL 树。我试图抓住控制本身。

示例:如果我有一个 TextBox 并使用上述任何一个,它将返回一个 TextBoxView 而我想要 TextBox 本身。

这发生在 PreviewLeftButtonDown 事件中。Sender 不是一个选项,因为 Sender 对我来说始终是 ListViewItem。如果我检查 e.OriginalSource 它仍然是 VisualTree 元素而不是实际控件。

如果需要,很乐意进一步解释。

谢谢

4

3 回答 3

4

您只需要沿着可视化树向上走,直到找到您想要的类型。这是一些代码的链接。

这是该链接中的代码

// walk up the visual tree to find object of type T, starting from initial object
public static T FindUpVisualTree<T>(DependencyObject initial) where T : DependencyObject
{
    DependencyObject current = initial;

    while (current != null && current.GetType() != typeof(T))
    {
         current = VisualTreeHelper.GetParent(current);
    }
    return current as T;   
}
于 2013-03-06T20:31:37.087 回答
1

向上走可视化树,直到找到UIElement

public UIElement FindUIElement(DependencyObject visualTreeNode)
{
    UIElement elem;
    while ((elem = (visualTreeNode as UIElement)) != null)
        visualTreeNode = VisualTreeHelper.GetParent(visualTreeNode);
    return elem;
}
于 2013-03-06T20:59:40.237 回答
1

我同意 mdm20 的唯一方法Textbox是遍历父级。事实上,这里是几年前提出的同一个问题的链接,答案相同。如果您想限制不必要的树遍历,那么您可以在点击 后停止搜索ListViewItem,因为高于该点的任何内容都不是您想要的。

但是,将最后一个链接和这个链接一起添加,在我看来,您实际上已经有了答案。如果TextBoxView返回 a,那么您就知道点击了一个文本框。您甚至可以缓存TextBox通过HitTestFilterCallBack潜在的传入,但这更多的是理论并且可能容易出错。但是,沿着这条路走下去,您可以测试TextBox通过过滤器的是否是TextBoxView

于 2013-03-07T01:53:13.907 回答