VisualTreeHelper.FindElementsInHostCoordinates 方法

定义

重载

FindElementsInHostCoordinates(Point, UIElement)

检索位于应用 UI 的指定 x-y 坐标点内的一组对象。 对象集表示共享该点的可视化树的组件。

FindElementsInHostCoordinates(Rect, UIElement)

检索位于应用 UI 的指定 Rect 帧中的一组对象。 对象集表示共享矩形区域的可视化树的组件,可能包含过度绘制的元素。

FindElementsInHostCoordinates(Point, UIElement, Boolean)

检索位于应用 UI 的指定 x-y 坐标点内的一组对象。 对象集表示共享该点的可视化树的组件。

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

检索位于应用 UI 的指定 Rect 帧中的一组对象。 对象集表示共享矩形区域的可视化树的组件,可能包含过度绘制的元素。

FindElementsInHostCoordinates(Point, UIElement)

检索位于应用 UI 的指定 x-y 坐标点内的一组对象。 对象集表示共享该点的可视化树的组件。

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)

参数

intersectingPoint
Point

用作确定点的点。 如果指定了) ,则此点使用应用窗口的坐标空间,而不是任何特定元素 (,也不使用 子树 的坐标空间。

subtree
UIElement

要搜索的对象。 如果 子树 对象存在于存在于指定 相交Point 坐标处的整个元素集中,则返回值仅包含 子树 对象以及 z 顺序比 子树更高的任何对象(按 z 顺序反转列出)。 如果 子树 对象不存在于 相交Point 坐标处,则返回值将为空。

返回

可视化树组合中指定点的一组可枚举 的 UIElement 对象,按 z 顺序反转列出。

属性

示例

这是一个示例实用工具方法,用于确定给定 Name 的元素是否存在于应用 UI 中 的 z 顺序中的任意位置。

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

注解

返回值不是单个元素,它是一个集合。 集合可以有多个元素,因为可以按 z 顺序堆叠多个 UI 元素。 输入事件处理程序公开的传统命中测试技术(例如 PointerPressed 事件的发送方值)只考虑具有最高 z 顺序的最顶层元素。 FindElementsInHostCoordinates 方法返回在应用 UI 中共享该点或区域的整个元素堆栈,按 z 顺序反转列出。 因此,使用 FindElementsInHostCoordinates 可用于检查有意或无意地堆叠元素的情况。 你可能想要更正呈现和命中测试的顺序,或者出于其他原因检查该顺序。

FindElementsInHostCoordinates 适用于三种方案:基本命中测试、筛选特定元素的命中测试,以及确定可视化树中是否存在在同一点过度绘制的元素。

基本命中测试

对于基本命中测试,目标是发现哪个元素在 x-y 坐标中给定点应用 UI 的 z 顺序中最高。 除了在呈现的 UI 中绘制最顶部的元素外,此元素也很重要,因为如果存在指针事件等用户交互,则它是报告的事件源。 你可能遇到过测试方案,即在发生任何输入事件之前,你想知道在 z 顺序顶部存在哪些元素,以便可以预测它,并可能更正 z 顺序放置中的任何错误。

对于此方案,应将感兴趣的命中测试点作为 相交Point 参数的值传递。 对于 子树 参数,可以将其传递为 null。 或者,你可以将 子树 指定为你知道是页面根视觉对象的某个元素,或者是想要成为命中测试的最后一站的某个元素。

z 顺序中最顶层的元素始终是 UIElement 项返回的 IEnumerable 中的第一个元素。 因此,对于基本命中测试,你通常只对第一个项目感兴趣。 IEnumerable 中的任何其他项都是其他元素,这些元素也位于此时,但以 z 顺序进一步返回,并绘制在第一个项下方。 进一步后面的元素不会报告自己作为此时输入事件的源,只有最顶层的元素会报告自己。

元素筛选命中测试

有时,你想知道 UI 中某个特定点是否存在特定元素。 如果是这样,则可以为 相交Point 指定该点,并将要查找的元素指定为 子树 参数。 如果返回值不为空,则表示元素确实存在于 UI 中的该点。 如果 元素是返回值中的第一项,则表示元素在 相交点处的 z 顺序中处于最顶层。 如果返回值中有其他项,并且 子树 不是第一个,则其他项表示在 交叉点 呈现的元素,这些元素在视觉上呈现在 z-order (,这些呈现在 子树 元素的顶部) 。 在这种情况下, 子树 是返回的 IEnumerable 中的最后一个元素,而不是第一个元素。

如果返回值为空,则表示 子树 元素不存在于任何 z 顺序值处。

查找过度绘制或查看完整的可视化树

UI 可以是动态的,尤其是在使用来自数据绑定的集合进行 UI 填充时。 因此,有时需要知道当前哪个元素位于顶部。 你可能在应用中预测用户可能交互的点,并验证你目前可能想要的交互。 对于此方案,通常指定一个 Point 值,该值表示某个已知点,例如 (0,0) ,该点当前是应用窗口中的有效坐标。 对于 子树 参数,可以将其传递为 null。 或者,你可以将 子树 指定为你知道是页面根视觉对象的某个元素,或者是想要成为命中测试的最后一站的某个元素。

注意

如果为子树传递 null,你可能会看到可视化树包含页级 XAML 未定义的元素,例如 Frame 元素和 ContentPresenter。 这些代码来自大多数适用于 UWP 应用的 Microsoft Visual Studio 项目模板中的典型应用初始化代码,该模板首先将 Frame 创建为 Window.Content 值。 FindElementsInHostCoordinates 方法所示的可视化树一直延伸到 Window.Content ,除非使用 子树 元素(如 Page 根)进行筛选。

在返回值中,你可能对中的每个项感兴趣。 因此,可以使用 foreach 或类似语言特定的技术来循环访问集合,并在其中每个元素上运行自己的逻辑。 请记住,该集合中的第一个元素是 z 顺序中最顶层的元素。

如果使用 C# 或 Microsoft Visual Basic 进行编程,则此方法的返回值类型投影为包含 UIElement的 IEnumerable 泛型集合。 如果使用 Visual C++ 组件扩展 (C++/CX) 进行编程,则此方法的返回类型为 IIterable<UIElement>。

另请参阅

适用于

FindElementsInHostCoordinates(Rect, UIElement)

检索一组对象,这些对象位于应用 UI 的指定 Rect 框架中。 对象集表示共享矩形区域的可视化树的组件,并且可能包含过度绘制的元素。

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)

参数

intersectingRect
Rect

用作确定区域的 Rect 。 此框架使用应用窗口的坐标空间,而不是 (的任何特定元素的坐标空间,如果指定) ,则不会使用 子树

subtree
UIElement

要搜索的对象。 如果 子树 对象存在于指定 相交Rect 内的总体元素集中,则返回值仅包含 子树 对象和在其空间上绘制的元素。 如果 intersectingRect 帧中不存在子树对象,则返回值将为空。

返回

一组可枚举的 UIElement 对象,这些对象位于指定的 Rect 框架的可视化树组合中。

属性

示例

给定此 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>

下面是使用不同 子树 值的 FindElementsInHostCoordinates 的一些示例用法和结果:

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
}

注解

返回值不是单个元素,它是一个集合。 集合可以有多个元素,因为多个 UI 元素可以按 z 顺序堆叠在一起,也可以有多个元素完全或部分地位于 相交帧 中。 输入事件处理程序公开的传统命中测试技术(例如 PointerPressed 事件的发送方值)只考虑具有最高 z 顺序的最顶层元素。 FindElementsInHostCoordinates 方法返回在应用 UI 中共享该点或区域的整个元素堆栈,这些元素按可视化树顺序 (通常与 XAML 声明顺序) 的反函数相同。 因此,使用 FindElementsInHostCoordinates 可用于检查有意或无意地堆叠元素的情况。 你可能想要更正呈现和命中测试的顺序,或者出于其他原因检查该顺序。

在一个区域中的 FindElementsInHostCoordinates 对于两种方案很有用:基本命中测试和针对特定元素进行筛选的命中测试。

基本命中测试

对于基本命中测试,目标是发现哪个元素在应用 UI 的 z 顺序中最高。 如果要对鼠标交互进行命中测试,则可以使用点,但对于面向触摸的命中测试,通常最好使用矩形区域。 你可能有命中测试方案,你希望在发生任何触摸事件之前知道哪些元素存在于 z-顺序的顶部。 或者,你可能有一个点,你想要扩展为一个矩形,以查看中心点附近的内容以及哪个元素可能是预期目标。

对于此方案,应传递感兴趣的命中测试矩形作为 相交Rect 参数的值。 对于 子树 参数,可以将其传递为 null。 或者,你可以将 子树 指定为你知道是页面根视觉对象的某个元素,或者是想要成为命中测试的最后一站的某个元素。

UIElement 项返回的 IEnumerable 中元素的顺序同时考虑区域中的坐标空间和 z 顺序。 因此,对于不处于最高 z 顺序的项,因此无法成为输入事件的源,可能会获得命中数。 若要确保,可以使用相同的 相交Rect ,但将感兴趣的元素作为 子树传递,对返回列表中的任何项执行元素筛选命中测试。

元素筛选命中测试

有时,你想知道 UI 的某个区域中是否存在特定元素。 如果是这样,可以指定 相交Rect 的区域,并将要查找的元素指定为 子树 参数。 如果返回值不为空,则表示该元素存在于该区域的某个位置。 在对某个区域进行命中测试时,返回集中的顺序对于确定 z 顺序没有用,因为该集包含多个 x-y 坐标处的元素。 该集混合了以各种 x-y 坐标绘制的元素,以及可能完全或部分透支的元素。 若要真正检查过度绘制的情况,请使用使用 PointFindElementsInHostCoordinates 重载,以便 x-y 坐标和可视化树顺序不再是一个因素。 请参阅 FindElementsInHostCoordinates (Point,UIElement)

如果返回值为空,则表示 区域中不存在子树 元素。

如果使用 C# 或 Microsoft Visual Basic 进行编程,此方法的返回值类型将投影为包含 UIElement的 IEnumerable 泛型集合。 如果使用 Visual C++ 组件扩展 (C++/CX) 进行编程,则此方法的返回类型为 IIterable<UIElement>。

另请参阅

适用于

FindElementsInHostCoordinates(Point, UIElement, Boolean)

检索位于应用 UI 的指定 x-y 坐标点内的一组对象。 对象集表示共享该点的可视化树的组件。

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)

参数

intersectingPoint
Point

用作确定点的点。 此点使用应用窗口的坐标空间,而不是 (的任何特定元素的坐标空间,如果) 指定,则不会使用 子树 的坐标空间。

subtree
UIElement

要搜索的对象。 如果 子树 对象存在于存在于指定 相交Point 坐标处的整个元素集中,则返回值仅包含 子树 对象和 Z 顺序高于 子树的任何对象(按 z 顺序反转列出)。 如果 子树 对象不存在于 相交Point 坐标处,则返回值将为空。

includeAllElements
Boolean

bool

true 将包含相交的所有元素,包括那些被认为对命中测试不可见的元素。 如果为 false ,则仅查找可见且可命中测试的元素。 默认值为 false

返回

确定位于指定点的可视化树组合中的一组可枚举 UIElement 对象,按 z 顺序反转列出。

属性

示例

给定此 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>

下面是使用不同 子树 值的 FindElementsInHostCoordinates 的一些示例用法和结果:

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
}

注解

如果元素既占用布局中的空间又“生成墨迹”,则被视为可命中测试元素。 对于具有 Brush 的元素,即使 Brush 不生成可见像素,任何非 null Brush 都被视为产生墨迹的内容。 例如,颜色设置为“透明”的 SolidColorBrush 仍会产生墨迹。 只有 null 画笔不产生墨迹。 不考虑 Opacity 属性。 即使元素的不透明度为 0,该元素仍会产生墨迹。

includeAllElements 参数设置为 true 时,将考虑不产生墨迹的元素进行命中测试。 在这种情况下,只要元素满足空间要求, (点与元素边界相交) ,结果中会包含它及其上级。

注意

某些特殊元素(如 SwapChainPanelMediaElement)没有画笔,但仍可以生成墨迹。

另请参阅

适用于

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

检索一组对象,这些对象位于应用 UI 的指定 Rect 框架中。 对象集表示共享矩形区域的可视化树的组件,并且可能包含过度绘制的元素。

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)

参数

intersectingRect
Rect

要用作确定区域的 矩形 。 此框架使用应用窗口的坐标空间,而不是 (的任何特定元素的坐标空间,如果) 指定,则不会使用 子树 的坐标空间。

subtree
UIElement

要搜索的对象。 如果 子树 对象存在于指定的 intersectingRect 内的总体元素集中,则返回值仅包含 子树 对象和在其空间顶部绘制的元素。 如果 intersectingRect 帧中不存在子树对象,则返回值将为空。

includeAllElements
Boolean

bool

true 将包含相交的所有元素,包括那些被认为对命中测试不可见的元素。 如果为 false ,则仅查找可见且可命中测试的元素。 默认值为 false

返回

一组可枚举的 UIElement 对象,确定位于指定 Rect 框架中的可视化树组合中。

属性

示例

给定此 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>

下面是使用不同子树值的 FindElementsInHostCoordinates 的一些示例用法和结果:

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
}

注解

如果元素既占用布局中的空间又“生成墨迹”,则被视为可命中测试元素。 对于具有 Brush 的元素,即使 Brush 不生成可见像素,任何非 null Brush 都被视为产生墨迹的内容。 例如,颜色设置为“透明”的 SolidColorBrush 仍会产生墨迹。 只有 null 画笔不产生墨迹。 不考虑 Opacity 属性。 即使元素的不透明度为 0,该元素仍会产生墨迹。

includeAllElements 参数设置为 true 时,将考虑不产生墨迹的元素进行命中测试。 在这种情况下,只要元素满足空间要求 (矩形与元素边界相交) ,结果中会包含它及其上级。

注意

某些特殊元素(如 SwapChainPanelMediaElement)没有画笔,但仍可以生成墨迹。

另请参阅

适用于