2013-03-06 19 views
0

这是一个WPF应用程序。LogicalTree直接在鼠标下控制否VisualTree

我试图直接控制鼠标,它证明是一个令人惊讶的痛苦。

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

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

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

如果需要,可以进一步解释。

谢谢

回答

1

我同意mdm20,只有这样,才能到Textbox是横穿父母。其实,here is a link to the same question asked a couple of years ago,具有相同的答案。如果你想限制不必要的树遍历,那么当你点击ListViewItem时,你可以停止搜索,因为任何高于此点的东西都不是你想要的东西。

但是,添加最后一个链接和this one together,实际上我觉得你已经有了答案。如果返回TextBoxView,那么您知道文本框已被击中。你甚至可以缓存经过HitTestFilterCallBack的输入TextBox,但这更多的是理论和可能的bug。但是,沿着这条道路,您可以测试通过过滤器的TextBox是否为TextBoxView的父亲

+0

这将是接受的答案 TextBoxView是我最终使用的,TextBoxView实际上包含了文本,而这正是我真正想要的,我想避免触发拖动,如果用户在文本框内拖动来选择一些文本。 谢谢 – tronious 2013-03-07 16:55:26

4

你只需要走向视觉树,直到你找到你想要的类型。以下是一些代码的link

下面是该链接的代码

// 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; 
} 
+0

感谢您的回复。 这会工作,但我不喜欢走树,因为这往往会发生。 此外,我会很担心无意中击中了错误的文本框(如果一个控件模板,并有复式文本框领导到父(=) 到底JustinPihony的回答满足了我的需求。 – tronious 2013-03-07 16:53:04

1

走了视觉树,直到找到一个UIElement

public UIElement FindUIElement(DependencyObject visualTreeNode) 
{ 
    UIElement elem; 
    while ((elem = (visualTreeNode as UIElement)) != null) 
     visualTreeNode = VisualTreeHelper.GetParent(visualTreeNode); 
    return elem; 
}