Udostępnij za pośrednictwem


VisualTreeHelper.FindElementsInHostCoordinates Method

Definition

Overloads

FindElementsInHostCoordinates(Point, UIElement)

Retrieves a set of objects that are located within a specified x-y coordinate point of an app UI. The set of objects represents the components of a visual tree that share that point.

FindElementsInHostCoordinates(Rect, UIElement)

Retrieves a set of objects that are located within a specified Rect frame of an app UI. The set of objects represents the components of a visual tree that share a rectangular area, and might include elements that overdraw.

FindElementsInHostCoordinates(Point, UIElement, Boolean)

Retrieves a set of objects that are located within a specified x-y coordinate point of an app UI. The set of objects represents the components of a visual tree that share that point.

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

Retrieves a set of objects that are located within a specified Rect frame of an app UI. The set of objects represents the components of a visual tree that share a rectangular area, and might include elements that overdraw.

FindElementsInHostCoordinates(Point, UIElement)

Retrieves a set of objects that are located within a specified x-y coordinate point of an app UI. The set of objects represents the components of a visual tree that share that point.

public:
 static IIterable<UIElement ^> ^ FindElementsInHostCoordinates(Point intersectingPoint, UIElement ^ subtree);
/// [Windows.Foundation.Metadata.DefaultOverload]
/// [Windows.Foundation.Metadata.Overload("FindElementsInHostCoordinatesPoint")]
 static IIterable<UIElement> FindElementsInHostCoordinates(Point const& intersectingPoint, UIElement const& subtree);
[Windows.Foundation.Metadata.DefaultOverload]
[Windows.Foundation.Metadata.Overload("FindElementsInHostCoordinatesPoint")]
public static IEnumerable<UIElement> FindElementsInHostCoordinates(Point intersectingPoint, UIElement subtree);
function findElementsInHostCoordinates(intersectingPoint, subtree)
Public Shared Function FindElementsInHostCoordinates (intersectingPoint As Point, subtree As UIElement) As IEnumerable(Of UIElement)

Parameters

intersectingPoint
Point

The point to use as the determination point. This point is using the coordinate space of the app window, not of any specific element (and not of subtree if specified).

subtree
UIElement

An object to search for. If the subtree object exists in the overall set of elements that exist at the specified intersectingPoint coordinates, then the return value contains only the subtree object and any objects that have a higher z-order than subtree, listed by inverse of z-order. If the subtree object doesn't exist at intersectingPoint coordinates, the return value will be empty.

Returns

An enumerable set of UIElement objects in the visual tree composition at the specified point, listed by inverse of z-order.

Attributes

Examples

This is an example utility method that determines whether an element of a given Name exists anywhere in the z-order at a Point in the UI of an app.

private bool DoesPointContainElement(Point testPoint, string elementName, UIElement referenceFrame)
{
    IEnumerable<UIElement> elementStack = 
      VisualTreeHelper.FindElementsInHostCoordinates(testPoint, referenceFrame);
    foreach (UIElement item in elementStack)
    {
        FrameworkElement feItem = item as FrameworkElement; 
//cast to FrameworkElement, need the Name property
        if (feItem != null)
        {
            if (feItem.Name.Equals(elementName))
            {
                 return true;
            }
        }
     }
     // elementName was not in this stack 
     return false;
}

Remarks

The return value is not a single element, it is a collection. The collection can have more than one element because there can be multiple UI elements stacked over each other in a z-order. The conventional hit-testing techniques exposed by the input event handlers, such as the sender value for a PointerPressed event, only account for the topmost element that has the highest z-order. FindElementsInHostCoordinates methods return the whole stack of elements that share that point or area in the app UI, listed by inverse of z-order. Using FindElementsInHostCoordinates can thus be useful for examining cases where you've intentionally or unintentionally stacked elements. You may want to correct the order for rendering and hit-testing, or examine that order for other reasons.

FindElementsInHostCoordinates is useful for three scenarios: basic hit testing, hit testing that is filtering for a specific element, and determining whether there are elements in a visual tree that are overdrawing at the same point.

Basic hit testing

For basic hit testing, the goal is to discover which element is highest in the z-order of an app UI at a given point in x-y coordinates. In addition to being the element that draws topmost in the rendered UI, this element is also important because it's the reported event source if there are user interactions such as pointer events. You might have hit testing scenarios where you want to know what element exists at the top z-order before any input event takes place, so that you can anticipate it and perhaps correct any mistakes in z-order placement.

For this scenario, you should pass the point you're interested in hit-testing as the value of the intersectingPoint parameter. For the subtree parameter, you can pass it as null. Or you can specify subtree to be some element that you know is the root visual of a page, or is otherwise some element that you want to be the final stop for hit testing.

The element that is topmost in the z-order is always the first element in the returned IEnumerable of UIElement items. So for basic hit testing you're usually only interested in that very first item. Any additional items in the IEnumerable are other elements that are also at that point but are further back in the z-order and are drawing underneath that first item. The elements further back wouldn't report themselves as the source for an input event at that point, only the topmost element would.

Element-filtered hit testing

Sometimes you want to know whether a specific element exists at a certain point in the UI. If so, you can specify that point for intersectingPoint and specify the element you're looking for as the subtree parameter. If the return value is not empty, that means that the element does exist at that point in the UI. If the element is the first item in the return value, that means the element is topmost in the z-order at intersectingPoint. If there are other items in the return value and subtree isn't first, the other items represent the elements rendering at intersectingPoint that are higher in z-order (visually, these render on top of the subtree element). In that case subtree is the last element in the returned IEnumerable, not the first.

If the return value is empty, that means that the subtree element didn't exist there, at any z-order value.

Looking for overdraw or looking at the complete visual tree

A UI can be dynamic, especially if you're using collections from data binding for UI population. So there's occasionally a need to know which element is currently on top. You might be anticipating points in the app where the user might interact and verifying that the interactions you intend are currently possible. For this scenario, you typically specify a Point value that represents some known point such as (0,0) that is currently a valid coordinate that's within your app window. For the subtree parameter, you can pass it as null. Or you can specify subtree to be some element that you know is the root visual of a page, or is otherwise some element that you want to be the final stop for hit testing.

Note

If you pass null for subtree, you might see that the visual tree contains elements that aren't defined by page-level XAML, such as a Frame element and ContentPresenter. These come from the typical app initialization code that exists in most of the Microsoft Visual Studio project templates for a UWP app, which first creates the Frame to be the Window.Content value. The visual tree as shown by FindElementsInHostCoordinates methods extends all the way to Window.Content unless you otherwise filter it with a subtree element such as a Page root.

In the return value, you might be interested in each of the items within. So you could use foreach or similar language-specific techniques to iterate the collection and run your own logic on each of these elements. Remember that the first element in that collection is the one that is topmost in z-order.

If you are programming using C# or Microsoft Visual Basic, the return value type of this method is projected as an IEnumerable generic collection that contains UIElement items. If you are programming using Visual C++ component extensions (C++/CX), the return type of this method is IIterable<UIElement>.

See also

Applies to

FindElementsInHostCoordinates(Rect, UIElement)

Retrieves a set of objects that are located within a specified Rect frame of an app UI. The set of objects represents the components of a visual tree that share a rectangular area, and might include elements that overdraw.

public:
 static IIterable<UIElement ^> ^ FindElementsInHostCoordinates(Rect intersectingRect, UIElement ^ subtree);
/// [Windows.Foundation.Metadata.Overload("FindElementsInHostCoordinatesRect")]
 static IIterable<UIElement> FindElementsInHostCoordinates(Rect const& intersectingRect, UIElement const& subtree);
[Windows.Foundation.Metadata.Overload("FindElementsInHostCoordinatesRect")]
public static IEnumerable<UIElement> FindElementsInHostCoordinates(Rect intersectingRect, UIElement subtree);
function findElementsInHostCoordinates(intersectingRect, subtree)
Public Shared Function FindElementsInHostCoordinates (intersectingRect As Rect, subtree As UIElement) As IEnumerable(Of UIElement)

Parameters

intersectingRect
Rect

The Rect to use as the determination area. This frame is using the coordinate space of the app window, not of any specific element (and not of subtree if specified).

subtree
UIElement

An object to search for. If the subtree object exists in the overall set of elements that exist within the specified intersectingRect, then the return value contains only the subtree object and elements that are drawing on top of its space. If the subtree object doesn't exist within the intersectingRect frame, the return value will be empty.

Returns

An enumerable set of UIElement objects that are in the visual tree composition in the specified Rect frame.

Attributes

Examples

Given this XAML UI:

<Canvas Name="canvas">
  <Rectangle Name="outermost" Fill="Red" Width="200" Height="200"/>
  <Rectangle Canvas.Left="40" Canvas.Top="40" Name="hidden" Fill="Green" Width="120" Height="120"/>
  <Rectangle Canvas.Left="40" Canvas.Top="40" Name="shown" Fill="Orange" Width="120" Height="120"/>
  <Rectangle Canvas.Left="80" Canvas.Top="80" Name="center" Fill="Yellow" Width="40" Height="40"/>
  <Rectangle Canvas.Left="190" Canvas.Top="190" Name="bottomright" Fill="Pink" Width="10" Height="10"/>
</Canvas>

Here are some example usages and results from FindElementsInHostCoordinates, using different subtree values:

private void Test(object sender, RoutedEventArgs e)
{
    IEnumerable<UIElement> hits;
    hits =  VisualTreeHelper.FindElementsInHostCoordinates(
      new Rect(75,75,50,50), canvas);
    foreach (UIElement element in hits)
    {
        //run logic here, such as log the results 
    }
// results in the following set of elements, listed by Name:
// center - the last declared XAML element is first returned, if within the area
// shown - renders, underneath 'center' in part of the area but visible on the edges
// hidden - entirely under 'shown', not visible but part of the area, an overdraw
// outermost - draws under all the above
// canvas - the 'subtree' value, and the last element reported

    hits = VisualTreeHelper.FindElementsInHostCoordinates(
      new Rect(75,75,50,50), center);
    foreach (UIElement element in hits) {
        //run logic here, such as log the results
    }
// results in only 'center', because it was 'subtree' and it's also topmost

    hits = VisualTreeHelper.FindElementsInHostCoordinates(
      new Rect(75,75,50,50), bottomright);
// results in an empty set, 'bottomright' isn't in the specified rect
}

Remarks

The return value is not a single element, it is a collection. The collection can have more than one element because there can be multiple UI elements stacked over each other in a z-order, and also multiple elements fully or partially in the intersectingRect frame. The conventional hit-testing techniques exposed by the input event handlers, such as the sender value for a PointerPressed event, only account for the topmost element that has the highest z-order. FindElementsInHostCoordinates methods return the whole stack of elements that share that point or area in the app UI, listed by visual tree order (which is usually the same as inverse of XAML declaration order). Using FindElementsInHostCoordinates can thus be useful for examining cases where you've intentionally or unintentionally stacked elements. You may want to correct the order for rendering and hit-testing, or examine that order for other reasons.

FindElementsInHostCoordinates over an area is useful for two scenarios: basic hit testing and hit testing that is filtering for a specific element.

Basic hit testing

For basic hit testing, the goal is to discover which element is highest in the z-order of an app UI. If you are hit-testing for a mouse interaction you might use a point, but for touch-oriented hit testing it's often appropriate to use a rectangular area. You might have hit testing scenarios where you want to know what element exists at the top z-order before any touch event takes place. Or you might have a point that you want to expand to be a rectangle to see what's near a center point and which element might be the intended target.

For this scenario, you should pass the rectangle you're interested in hit-testing as the value of the intersectingRect parameter. For the subtree parameter, you can pass it as null. Or you can specify subtree to be some element that you know is the root visual of a page, or is otherwise some element that you want to be the final stop for hit testing.

The order of element in the returned IEnumerable of UIElement items is accounting for both coordinate space in the area and for the z-order. So it's possible to get hits for items that are not at the highest z-order and therefore couldn't be the source of input events. To make sure, you can do an element-filtered hit test for any items from the returned list that you're interested in, using the same intersectingRect but passing the element of interest as subtree.

Element-filtered hit testing

Sometimes you want to know whether a specific element exists within an area of the UI. If so, you can specify that area for intersectingRect and specify the element you're looking for as the subtree parameter. If the return value is not empty, that means that the element exists somewhere in that area. When you're hit-testing an area, the order in the return set isn't as useful for determining z-order because the set includes elements at more than one x-y coordinate. The set has a mix of elements drawing at various x-y coordinates and also elements that might be fully or partially overdrawn. To really examine an overdraw situation, use the overloads of FindElementsInHostCoordinates that use a Point, so that the x-y coordinates and the visual tree order are no longer a factor. See FindElementsInHostCoordinates(Point,UIElement).

If the return value is empty, that means that the subtree element didn't exist in the area.

If you are programming using C# or Microsoft Visual Basic, the return value type of this method is projected as an IEnumerable generic collection that contains UIElement items. If you are programming using Visual C++ component extensions (C++/CX), the return type of this method is IIterable<UIElement>.

See also

Applies to

FindElementsInHostCoordinates(Point, UIElement, Boolean)

Retrieves a set of objects that are located within a specified x-y coordinate point of an app UI. The set of objects represents the components of a visual tree that share that point.

public:
 static IIterable<UIElement ^> ^ FindElementsInHostCoordinates(Point intersectingPoint, UIElement ^ subtree, bool includeAllElements);
/// [Windows.Foundation.Metadata.DefaultOverload]
/// [Windows.Foundation.Metadata.Overload("FindAllElementsInHostCoordinatesPoint")]
 static IIterable<UIElement> FindElementsInHostCoordinates(Point const& intersectingPoint, UIElement const& subtree, bool const& includeAllElements);
[Windows.Foundation.Metadata.DefaultOverload]
[Windows.Foundation.Metadata.Overload("FindAllElementsInHostCoordinatesPoint")]
public static IEnumerable<UIElement> FindElementsInHostCoordinates(Point intersectingPoint, UIElement subtree, bool includeAllElements);
function findElementsInHostCoordinates(intersectingPoint, subtree, includeAllElements)
Public Shared Function FindElementsInHostCoordinates (intersectingPoint As Point, subtree As UIElement, includeAllElements As Boolean) As IEnumerable(Of UIElement)

Parameters

intersectingPoint
Point

The point to use as the determination point. This point is using the coordinate space of the app window, not of any specific element (and not of subtree if specified).

subtree
UIElement

An object to search for. If the subtree object exists in the overall set of elements that exist at the specified intersectingPoint coordinates, then the return value contains only the subtree object and any objects that have a higher z-order than subtree, listed by inverse of z-order. If the subtree object doesn't exist at intersectingPoint coordinates, the return value will be empty.

includeAllElements
Boolean

bool

true to include all elements that intersect, including those elements considered to be invisible to hit testing. false to find only visible, hit-testable elements. The default is false.

Returns

An enumerable set of UIElement objects that are determined to be located in the visual tree composition at the specified point, listed by inverse of z-order.

Attributes

Examples

Given this XAML UI:

<Canvas Name="canvas">
  <Rectangle Name="outermost" Fill="Red" Width="200" Height="200"/>
  <Rectangle Canvas.Left="40" Canvas.Top="40" Name="hidden" Fill="Green" Width="120" Height="120"/>
  <Rectangle Canvas.Left="40" Canvas.Top="40" Name="shown" Fill="Orange" Width="120" Height="120"/>
  <Rectangle Canvas.Left="80" Canvas.Top="80" Name="center" Fill="Yellow" Width="40" Height="40"/>
  <Rectangle Canvas.Left="190" Canvas.Top="190" Name="bottomright" Fill="Pink" Width="10" Height="10"/>
</Canvas>

Here are some example usages and results from FindElementsInHostCoordinates, using different subtree values:

private void Test(object sender, RoutedEventArgs e)
{
    IEnumerable<UIElement> hits;
    hits =  VisualTreeHelper.FindElementsInHostCoordinates(
      new Point(100,100), canvas, true);
    foreach (UIElement element in hits)
    {
        //run logic here, such as log the results 
    }
// results in the following set of elements, listed by Name:
// center - the element that is topmost in z-order at 100,100
// shown - also renders at 100,100 but is underneath 'center'
// hidden - is entirely underneath 'shown', 
//   and lower in z-order because 'hidden' declared before 'shown' in XAML
// outermost - draws under all the above at 100,100
// canvas - the 'subtree' value, so that's the last element reported

    hits = VisualTreeHelper.FindElementsInHostCoordinates(
      new Point(100, 100), center, true);
    foreach (UIElement element in hits) {
        //run logic here, such as log the results
    }
// results in 'center', because it is 'subtree' and also topmost

    hits = VisualTreeHelper.FindElementsInHostCoordinates(
      new Point(100, 100), bottomright, true);
// results in an empty set, 'bottomright' doesn't render at 100,100
}

Remarks

An element is considered hit-testable if it both occupies space in the layout and "produces ink". For elements that have a Brush, any non-null Brush is considered something that produces ink, even if the Brush doesn't produce visible pixels. For example, a SolidColorBrush with its color set to Transparent still produces ink. Only a null brush does not produce ink. The Opacity property is not considered. The element still produces ink even if it's Opacity is 0.

When the includeAllElements parameter is set to true, elements that don't produce ink are considered for hit-testing. In this case, as long as the element meets the spatial requirements (the point intersects the element bounds), then it and its ancestors are included in the results.

Note

Some special elements, like SwapChainPanel and MediaElement, don’t have a brush but can still produce ink.

See also

Applies to

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

Retrieves a set of objects that are located within a specified Rect frame of an app UI. The set of objects represents the components of a visual tree that share a rectangular area, and might include elements that overdraw.

public:
 static IIterable<UIElement ^> ^ FindElementsInHostCoordinates(Rect intersectingRect, UIElement ^ subtree, bool includeAllElements);
/// [Windows.Foundation.Metadata.Overload("FindAllElementsInHostCoordinatesRect")]
 static IIterable<UIElement> FindElementsInHostCoordinates(Rect const& intersectingRect, UIElement const& subtree, bool const& includeAllElements);
[Windows.Foundation.Metadata.Overload("FindAllElementsInHostCoordinatesRect")]
public static IEnumerable<UIElement> FindElementsInHostCoordinates(Rect intersectingRect, UIElement subtree, bool includeAllElements);
function findElementsInHostCoordinates(intersectingRect, subtree, includeAllElements)
Public Shared Function FindElementsInHostCoordinates (intersectingRect As Rect, subtree As UIElement, includeAllElements As Boolean) As IEnumerable(Of UIElement)

Parameters

intersectingRect
Rect

The Rect to use as the determination area. This frame is using the coordinate space of the app window, not of any specific element (and not of subtree if specified).

subtree
UIElement

An object to search for. If the subtree object exists in the overall set of elements that exist within the specified intersectingRect, then the return value contains only the subtree object and elements that are drawing on top of its space. If the subtree object doesn't exist within the intersectingRect frame, the return value will be empty.

includeAllElements
Boolean

bool

true to include all elements that intersect, including those elements considered to be invisible to hit testing. false to find only visible, hit-testable elements. The default is false.

Returns

An enumerable set of UIElement objects that are determined to be located in the visual tree composition in the specified Rect frame.

Attributes

Examples

Given this XAML UI:

<Canvas Name="canvas">
  <Rectangle Name="outermost" Fill="Red" Width="200" Height="200"/>
  <Rectangle Canvas.Left="40" Canvas.Top="40" Name="hidden" Fill="Green" Width="120" Height="120"/>
  <Rectangle Canvas.Left="40" Canvas.Top="40" Name="shown" Fill="Orange" Width="120" Height="120"/>
  <Rectangle Canvas.Left="80" Canvas.Top="80" Name="center" Fill="Yellow" Width="40" Height="40"/>
  <Rectangle Canvas.Left="190" Canvas.Top="190" Name="bottomright" Fill="Pink" Width="10" Height="10"/>
</Canvas>

Here are some example usages and results from FindElementsInHostCoordinates, using different subtree values:

private void Test(object sender, RoutedEventArgs e)
{
    IEnumerable<UIElement> hits;
    hits =  VisualTreeHelper.FindElementsInHostCoordinates(
      new Rect(75,75,50,50), canvas, true);
    foreach (UIElement element in hits)
    {
        //run logic here, such as log the results 
    }
// results in the following set of elements, listed by Name:
// center - the last declared XAML element is first returned, if within the area
// shown - renders, underneath 'center' in part of the area but visible on the edges
// hidden - entirely under 'shown', not visible but part of the area, an overdraw
// outermost - draws under all the above
// canvas - the 'subtree' value, and the last element reported

    hits = VisualTreeHelper.FindElementsInHostCoordinates(
      new Rect(75,75,50,50), center, true);
    foreach (UIElement element in hits) {
        //run logic here, such as log the results
    }
// results in only 'center', because it was 'subtree' and it's also topmost

    hits = VisualTreeHelper.FindElementsInHostCoordinates(
      new Rect(75,75,50,50), bottomright, true);
// results in an empty set, 'bottomright' isn't in the specified rect
}

Remarks

An element is considered hit-testable if it both occupies space in the layout and "produces ink". For elements that have a Brush, any non-null Brush is considered something that produces ink, even if the Brush doesn't produce visible pixels. For example, a SolidColorBrush with its color set to Transparent still produces ink. Only a null brush does not produce ink. The Opacity property is not considered. The element still produces ink even if it's Opacity is 0.

When the includeAllElements parameter is set to true, elements that don't produce ink are considered for hit-testing. In this case, as long as the element meets the spatial requirements (the rect intersects the element bounds), then it and its ancestors are included in the results.

Note

Some special elements, like SwapChainPanel and MediaElement, don’t have a brush but can still produce ink.

See also

Applies to