确定对象是否可见且可单击

时间:2011-03-13 07:34:30

标签: silverlight windows-phone-7

我正在寻找有效确定控件是否实际可见且可点击的方法。我的意思是除了检查对象的Visibility属性。

我可以检查RenderSize,如果任何父元素被折叠,那将是[0,0]。所以这也很简单。我也可以遍历可视化树,看看是否所有元素的不透明度都设置为1。

我不知道如何很好地检查这些情况:

  1. 该对象受到其他对象的阻碍。显然,可以使用FindElementsInHostCoordinates()并进行计算以找出这些对象阻碍了多少,但这可能是一种矫枉过正。我还可以制作有问题的对象的“屏幕截图”和整个页面的“屏幕截图”,并检查我的对象应该与实际对象像素匹配的像素。这听起来也像是一种矫枉过正。
  2. 对象受到仍然“吞下”点击(点按)的透明对象的阻碍。在这种情况下,第一个问题的解决方法仍然可能失败。
  3. 更新(另一个方案)

    1. 对象超出父对象/屏幕的范围。除了大量的计算之外,还有其他方法可以解决这个问题吗?
    2. 有更好的想法吗?我想念一下吗?

      谢谢!

2 个答案:

答案 0 :(得分:3)

您可以以编程方式测试元素的Visiblity和HitTestVisible属性,但超出此,如果点击事件将转发到元素或被吞下,则无法实际测试在它之上的元素 - 因为阻塞或转发点击可能发生在事件处理程序方法中,而这些方法根本无法以通用方式确定。

采用以下示例:

  • 您想要测试ParentElement面板是否可点击其上有ChildElement
  • ChildElement附加了一个处理click事件的事件处理程序,它是可见的,其HitTestVisible属性设置为true。
  • 基于此,您还无法确定该事件是否会转发到ParentElement:在ChildElement的点击事件处理程序中,它可以将事件的Handled属性设置为true会阻止ParentPanel接收事件,也可能将其保留为false,使ParentPanel收到事件。

因此,如果涉及自定义EventHandler,您将无法确定元素是否可点击。您可以做的最多是检查子元素和父元素的VisiblityIsHitTestVisible属性,并使用TransformToVisual方法检查子元素/父元素相对于彼此的呈现位置。

答案 1 :(得分:0)

您正在寻找VisualTreeHelper.FindElementsInHostCoordinates。返回的第一个元素将是鼠标点击/点击该像素的元素。当然,正如Gergely所说,你无法判断该元素是否会忽略点击并将其传递给你。

这是一个示例函数:

// pass in a point and the UIElement that the point is relative to
// (or null if the point is relative to the root visual)
public static UIElement HitTest(Point p, UIElement relativeTo = null)
{
    if (relativeTo != null)
        p = relativeTo.TransformToVisual(Application.Current.RootVisual)
    return VisualTreeHelper
          .FindElementsInHostCoordinates(p, Application.Current.RootVisual)
          .FirstOrDefault();
}