开发者

Is there any way to hit test for a disabled control?

I'm tryin开发者_开发知识库g to detect the control under the mouse cursor, regardless of whether the control is enabled or not.

VisualTreeHelper.FindElementsInHostCoordinates ignores controls that have their IsEnabled property set to false. Is there any way to change this behavior, or any other way to find the controls at a specific screen location?

Thanks.


You could implement your own recursive method to search the subtree and transform each element to the application's root visual in order to get its "absolute" bounds and then test to see if the "absolute" mouse point is within that region.

This might not be exactly what you need but should get you started. I basically made a replacement FindElementsInHostCoordinates with the same signature so it can be used in the same manner in your MouseMove handler. This method only tries to "hit test" FrameworkElements since it needs to know the ActualWidth and ActualHeight to calculate the hit region.

private IEnumerable<UIElement> FindAllElementsInHostCoordinates(Point intersectingPoint, UIElement subTree)
{
    var results = new List<UIElement>();

    int count = VisualTreeHelper.GetChildrenCount(subTree);

    for (int i = 0; i < count; i++)
    {
        var child = VisualTreeHelper.GetChild(subTree, i) as FrameworkElement;

        if (child != null)
        {
            GeneralTransform gt = child.TransformToVisual(Application.Current.RootVisual as UIElement);
            Point offset = gt.Transform(new Point(0, 0));
            Rect elementBounds = new Rect(offset.X, offset.Y, child.ActualWidth, child.ActualHeight);

            if (IsInBounds(intersectingPoint, elementBounds))
            {
                results.Add(child as UIElement);
            }
        }

        results.AddRange(FindAllElementsInHostCoordinates(intersectingPoint, child));
    }

    return results;
}

private bool IsInBounds(Point point, Rect bounds)
{
    if (point.X > bounds.Left && point.X < bounds.Right &&
        point.Y < bounds.Bottom && point.Y > bounds.Top)
    {
        return true;
    }

    return false;
}

You would then just need to make sure the point you are passing in from the MouseMove handler is relative to Application.Current.RootVisual:

IEnumerable<UIElement> elements = FindAllElementsInHostCoordinates(e.GetPosition(Application.Current.RootVisual), this);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜