有没有办法对禁用的控件进行命中测试?

发布于 2024-09-18 14:35:51 字数 208 浏览 9 评论 0原文

我试图检测鼠标光标下的控件,无论该控件是否启用。

VisualTreeHelper.FindElementsInHostCooperatives 会忽略 IsEnabled 属性设置为 false 的控件。有什么方法可以改变这种行为,或者有任何其他方法可以在特定的屏幕位置找到控件?

谢谢。

I'm trying 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南城追梦 2024-09-25 14:35:51

您可以实现自己的递归方法来搜索子树并将每个元素转换为应用程序的根视觉对象,以获得其“绝对”边界,然后测试“绝对”鼠标点是否在该区域内。

这可能不完全是您所需要的,但应该可以帮助您入门。我基本上使用相同的签名进行了替换 FindElementsInHostCooperatives ,因此可以在 MouseMove 处理程序中以相同的方式使用它。此方法仅尝试“命中测试”FrameworkElements,因为它需要知道 ActualWidth 和 ActualHeight 来计算命中区域。

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;
}

然后,您只需确保从 MouseMove 处理程序传入的点是相对于 Application.Current.RootVisual 的:

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

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文