2011-03-13 215 views
6

我正在寻找方法来有效地确定控件是否实际可见并可点击。我的意思是超出检查对象的可见性属性。确定对象是否可见并可点击

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

我不知道究竟怎么很好地检查有这些情景:

  1. 目的是通过阻碍一些其他物体。显然,可以使用FindElementsInHostCoordinates()并进行计算来找出这些对象有多少阻塞,但这可能是一种矫枉过正。我也可以对所讨论的对象进行“截图”,并对整个页面进行“截图”,并检查像素应该与实际对象像素匹配的像素。这听起来也是一种矫枉过正。
  2. 该物体被一个透明物体阻挡,该物体仍然“吞下”点击(水龙头)。在这种情况下,第一个问题的解决方法仍然可能会失败。

更新(多一个的情况)

  1. 目的是出了父对象/屏幕的界。除了很多计算之外,还有其他方法可以找到它吗?

有没有更好的办法?我想念什么?

谢谢!

回答

3

可以编程测试可视性和元素的HitTestVisible财产,但超过这个你无法实际测试如果click事件将被转发到该元素或者在它上面的元素吞噬 - 因为堵或转发点击可能发生在事件处理程序方法中,您无法以通用方式确定。

看看下面的例子:

  • 你想测试,如果ParentElement面板点击在其上有
  • ChildElement一个ChildElement具有连接到它的事件处理程序处理click事件,它是可见并且其HitTestVisible属性设置为true。
  • 基于此,您还不能确定事件是否会被转发至ParentElement:在ChildElement的点击事件处理程序中,它可以将事件的Handled属性设置为true,以阻止ParentPanel接收事件,或者可以将其保留在假的情况下,使ParentPanel接收事件。

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

+0

谢谢!我添加了另一个可疑的情况。有任何想法吗? – 2011-03-13 08:28:00

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(); 
}