【问题标题】:UWP Is it Possible To Override Hit Testing?UWP 是否可以覆盖命中测试?
【发布时间】:2019-03-02 04:58:09
【问题描述】:

我在编写 WPF UI 多年后来到 UWP。

使用 WPF 控件,可以通过重写控件的 HitTestCore 方法来提供自定义命中测试逻辑,如下所示:

protected override HitTestResult HitTestCore(PointHitTestParameters params)
{
    //Do some kind of test on params.HitPoint
    if (HitPointIsOverTheControl(params.HitPoint))
        return new PointHitTestResult(this, params.HitPoint);
    else
        return null;
}

我一直在成功地使用这种方法来测试鼠标是否在任何不规则形状的 PNG 图像上(在图像控件中),方法是测试当前鼠标点正下方的图像像素,看看它是否有alpha通道字节值为0,如果是则在上述函数中返回null。

换句话说,这种方法允许我通过 PNG alpha 通道掩码选择可见控件堆栈中可能位于其下方的任何内容。而且效果非常好。

现在到 UWP...

我在 UWP 框架中找不到与上述类似的方法,因此我怀疑 UWP 中没有“命中测试覆盖”。

谁能告诉我这种方法在 UWP 中是否仍然可行,如果不可行,我可以使用其他方法来实现相同的结果吗?

谢谢

编辑:示例

假设有 2 个图像控件彼此重叠,最上面的控件是一个中间有一个洞的黄色圆圈的图像,底部的图像是一个被顶部控件完全覆盖的纯蓝色方块,但可以通过圆圈中的孔部分看到。

现在我希望能够 a) 通过单击圆圈的黄色部分来移动圆圈,或者 b) 通过单击圆圈中的孔从下方移动蓝色方块。

好的。当我将鼠标移到黄色圆圈上时,它会触发 PointerMoved 事件,然后我可以确定鼠标是否位于 PNG 图像掩码的一部分上。到目前为止一切顺利。

现在假设鼠标在圆圈中间的孔上,我真的想开始从正方形而不是圆圈接收所有指针和操作事件。我能想到的唯一方法是在鼠标悬停在图像的“洞”部分时在圆圈上设置属性“IsHitTestVisible=false”,并在鼠标悬停时在圆圈上设置“IsHitTestVisible=true”图像的“黄色”部分。

这种方法的问题在于,一旦我在圆圈上设置了“IsHitTestVisible=false”,它将不再引发更多的 PointerMoved 事件。

换句话说,现在开始更改 PointerMoved 事件中的 IsHitTestVisible 属性为时已晚,因此为什么能够在 WPF 中覆盖 HitTestCore 非常有用,因为这发生在引发 Pointer 事件之前。

所以现在我知道 HitTestCore 覆盖在 UWP 中不可用(说实话,这真的很遗憾),还有其他方法可以实现我所描述的吗?例如,当指针事件和触摸事件由第一个控件引发时,我是否可以将它们转发到第二个控件,并且这样做也会让第一个控件忽略这些事件?

欢迎任何想法

【问题讨论】:

  • 你找到方法了吗?谢谢
  • 对不起,没有。对延迟回复表示歉意。

标签: uwp hittest


【解决方案1】:

UWP Image控件是密封类,不能被继承,Image控件中没有HitTestCore方法。根据您的要求,您可以处理PointerMoved 事件,该事件可以监视鼠标在控制点击区域中的移动并获取当前位置。

private void Image_PointerMoved(object sender, PointerRoutedEventArgs e)
{
    var point = e.GetCurrentPoint(sender as UIElement).Position;

    System.Diagnostics.Debug.WriteLine(point.ToString());
}

【讨论】:

  • 感谢 Nico 的回复,但这并没有给我我想要的东西。我用一个示例场景编辑了我的帖子。如果您有任何其他想法,我们将不胜欢迎
  • UIElement 也有PointerEnteredPointerExited 事件,您可以在这些事件处理程序中设置IsHitTestVisible。有关更多详细信息,您可以参考此documentation
  • 谢谢尼科。这是部分解决方案。它适用于单击/拖动场景,但不适用于鼠标悬停/反馈场景,因为需要有一种方法可以在鼠标在单击任何对象之前在对象上移动时即时打开和关闭命中测试。但是 PointerEntered/Exited 给了我一些我需要的东西
猜你喜欢
  • 2017-10-22
  • 2022-11-23
  • 2014-11-06
  • 2019-02-24
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
相关资源
最近更新 更多