开发者

Determining if object is visible and clickable

I'm looking for ways to effectively determine if a control is actually visible and clickable. I mean beyond checking Visibility property of the object.

I can check RenderSize and that would be [0,0] if any of the parent elements is collapsed. So this is simple too. I can also traverse up the visual tree and see if Opacity of all elements is set to 1开发者_如何学运维.

What I don't know how to check nicely are these scenarios:

  1. The object is obstructed by some other object. Obviously it's possible to use FindElementsInHostCoordinates() and do computations to find out how much these objects obstruct but this could be an overkill. I can also make a "screenshot" of the object in question and "screenshot" of the whole page and check if pixels where my object should be match the actual object pixels. That sounds like an overkill too.
  2. The object is obstructed by a transparent object that still "swallows" clicks (taps). The workarounds for the first problem could still fail in this scenario.

Update (one more scenario)

  1. The object is out of bounds of the parent object/screen. Is there any other way to find this out except for lots of calculations?

Any better ideas? Do I miss something?

Thanks!


You can programatically test the Visiblity and the HitTestVisible property of an element, however beyond this you can't actually test if a click event will be forwarded to the element or swallowed by elements on top of it - because blocking or forwarding clicks can happen in event handler methods which you simply can't determine in a generic way.

Take the following example:

  • You want to test if the ParentElement panel is clickable that has a ChildElement on it
  • ChildElement has an event handler attached to it that handles the click event, it's visible and its HitTestVisible property is set to true.
  • Based on this you can't yet decide if the event will be forwarded to ParentElement: in the click event handler of ChildElement it can set the event's Handled property to true that would stop the ParentPanel receiving the event or it could leave it at false, making the ParentPanel receive the event.

Thus if there are custom EventHandlers involved, you won't be able to tell for certain whether an element is clickable or not. The most you can do is check the Visiblity and IsHitTestVisible properties on child and parent elements and check where the children / parents are rendered relative to each other using the TransformToVisual method.


You are looking for VisualTreeHelper.FindElementsInHostCoordinates. The first element returned will be the element that would get a mouse click/tap on that pixel. Of course, as Gergely said, you can't tell if that element would ignore the click and pass it on to you.

Here's a sample function:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜