代码之家  ›  专栏  ›  技术社区  ›  Greg

有什么方法可以测试一个禁用的控件吗?

  •  3
  • Greg  · 技术社区  · 15 年前

    VisualTreeHelper.FindElementsInHostCoordinates 忽略具有 IsEnabled false . 是否有任何方法可以更改此行为,或者有任何其他方法可以在特定屏幕位置找到控件?

    谢谢。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Dan Auclair    15 年前

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

    确切地 FindElementsInHostCoordinates 具有相同的签名,因此可以在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);