无论控件是否启用,我都试图检测鼠标光标下的控件。
VisualTreeHelper.FindElementsInHostCoordinates
会忽略将IsEnabled
属性设置为false
的控件。有没有办法改变这种行为,或者在特定的屏幕位置找到控件的任何其他方法?
感谢。
答案 0 :(得分:1)
您可以实现自己的递归方法来搜索子树并将每个元素转换为应用程序的根视觉,以获得其“绝对”边界,然后测试以查看“绝对”鼠标点是否在该区域内。 / p>
这可能不是完全你需要的东西,但应该让你开始。我基本上使用相同的签名创建了替换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);