我有一个 WrapPanel 包含任意数量的锯齿状大小的元素。我想为我的项目实现拖动选择。
如何对一个点进行 HitTest 似乎很明显,但是如何找到矩形区域内的所有项目?
您可以将VisualTreeHelper.HitTest与GeometryHitTestParameters参数和HitTestFilterCallback 一起使用,以检查 Visual 是否是 Panel 的直接子级。
像这样的东西:
var selectedElements = new List<DependencyObject>();
var rect = new RectangleGeometry(...);
var hitTestParams = new GeometryHitTestParameters(rect);
var resultCallback = new HitTestResultCallback(
result => HitTestResultBehavior.Continue);
var filterCallback = new HitTestFilterCallback(
element =>
{
if (VisualTreeHelper.GetParent(element) == panel)
{
selectedElements.Add(element);
}
return HitTestFilterBehavior.Continue;
});
VisualTreeHelper.HitTest(
panel, filterCallback, resultCallback, hitTestParams);
它看起来有点复杂,但HitTestFilterCallback
有必要在视觉树中获取所有视觉对象,而不仅仅是那些实际被击中的对象。例如,如果您的面板包含 Label 控件,HitTestResultCallback
则只会为每个 Label 的 Border 和 TextBlock 子 Visuals 调用。
用于控制命中测试可见性的选项是IsHitTestVisible
属性。无论使用哪个画笔呈现 UIElement,此属性都允许您控制命中测试可见性。
此外,您想将填充设置为透明
<Rectangle Width="200" Height="200" Margin="170,23,12,35" Fill="Transparent" IsHitTestVisible="True" />