Question

This is a WPF application.

I'm trying to get the control directly under the mouse and it's proving to be a surprising pain.

Mouse.DirectlyOver, InputHitTest and VisualTreeHelper.HitTest all reference the VISUAL tree. I'm trying to grab the control itself.

Example: If I have a TextBox and use any of the above, it will return a TextBoxView whereas I want the TextBox itself.

This is happening inside of a PreviewLeftButtonDown event. Sender is not an option as Sender is always a ListViewItem for me. If I check e.OriginalSource it is still the VisualTree element and not the actual control.

Happy to explain further if need be.

Thanks

Was it helpful?

Solution 2

I agree with mdm20 that the only way to get to the Textbox is by traversing up to the parent. In fact, here is a link to the same question asked a couple of years ago, with the same answer. If you want to limit unnecessary tree traversal, then you could stop searching once you hit the ListViewItem, as anything above that point is not what you are looking for anyway.

However, add the last link and this one together, and it actually seems to me that you already have your answer. If a TextBoxView is returned, then you know that a textbox was hit. You could even cache the incoming TextBox that goes through the HitTestFilterCallBack potentially, but that is more of a theory and possibly bug prone. However, going down that path, you could just test if the TextBox coming through the filter is the parent of the TextBoxView

OTHER TIPS

You just need to walk up the visual tree until you find the type you want. Here's a link to some code.

Here's the code from that 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;   
}

Walk up the visual tree until you find a UIElement:

public UIElement FindUIElement(DependencyObject visualTreeNode)
{
    UIElement elem;
    while ((elem = (visualTreeNode as UIElement)) != null)
        visualTreeNode = VisualTreeHelper.GetParent(visualTreeNode);
    return elem;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top