Язык

VisualTreeHelper Класс

Определение

Предоставляет служебные методы, которые можно использовать для обхода связей объектов (вдоль осей дочерних объектов или родительских объектов) в визуальном дереве приложения.

public ref class VisualTreeHelper sealed
/// [Windows.Foundation.Metadata.ContractVersion(Microsoft.UI.Xaml.WinUIContract, 65536)]
/// [Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
/// [Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
class VisualTreeHelper final
[Windows.Foundation.Metadata.ContractVersion(typeof(Microsoft.UI.Xaml.WinUIContract), 65536)]
[Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
[Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
public sealed class VisualTreeHelper
Public NotInheritable Class VisualTreeHelper
Наследование
Object Platform::Object IInspectable VisualTreeHelper
Атрибуты

Примеры

Ниже приведен пример функции служебной программы, которая может скопировать список дочерних элементов определенного типа из визуального дерева. В нем используются базовые методы обхода GetChildrenCount и GetChild. Он использует рекурсию, чтобы элементы не могли находиться независимо от того, какой уровень вложения в промежуточных контейнерах существует. Он также использует метод расширения IsSubclassOf из System.Reflection , который расширяет сравнение типов для рассмотрения подтипов в качестве совпадения для типа.

internal static void FindChildren<T>(List<T> results, DependencyObject startNode)
  where T : DependencyObject
{
    int count = VisualTreeHelper.GetChildrenCount(startNode);
    for (int i = 0; i < count; i++)
    {
        DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
        if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
        {
            T asType = (T)current;
            results.Add(asType);
        }
        FindChildren<T>(results, current);
    }
}

Комментарии

Визуальное дерево

Цель класса VisualTreeHelper — помочь в обнаружении объектов, которые вы ищете в дереве объектов среды выполнения, но для вашего сценария нет более прямого API связи объектов. Иногда точного типа или имени объекта не будет известно. Или, возможно, вы знаете, что конкретный объект отображается где-то в дереве, но вы не знаете точное положение. Для этих типов сценариев VisualTreeHelper полезно, так как вы можете рекурсивно найти все объекты в визуальном дереве, а затем просмотреть этот набор и найти совпадение на основе ваших критериев.

Визуальное дерево для приложения может быть концептуально представлено как отфильтрованное представление более крупного дерева объектов объектов и свойств приложения. В визуальном дереве присутствуют только объекты, имеющие последствия отрисовки. Например, класс коллекции не будет частью визуального дерева. Вместо этого визуальное дерево абстрагирует любую коллекцию в понятие "дочерние".

Однако визуальное дерево также может включать объекты, которые не представлены как элементы XAML в разметке XAML страницы. Это связано с тем, что визуальное дерево добавляет объекты, которые являются составными частями элементов управления. Эти элементы управления могут поступать из примененного шаблона элемента управления, который обычно XAML из элемента словаря ресурсов или из докладчика.

Разметка XAML и визуальное дерево не соответствуют точно узлу для узла, так как XAML предназначен для разметки и простоты использования во время определения разметки, поэтому иногда он содержит дополнительные элементы. Например, XAML имеет элементы свойств, которые задают значения свойств, если один элемент найден в другом. В визуальном дереве это просто будет выглядеть как свойство объекта, задается другим объектом. XAML также имеет концепцию свойства содержимого, в котором заданное свойство не указано явным образом в разметке. Дополнительные сведения о конкретной терминологии и правилах для XAML см. в обзоре XAML.

Визуальное дерево используется внутренне для процесса отрисовки пользовательского интерфейса, но знание структуры визуального дерева важно для определенных сценариев, таких как написание или замена шаблона элемента управления, или анализ структуры и частей элемента управления во время выполнения. В этих сценариях среда выполнения Windows предоставляет API VisualTreeHelper, который может изучать визуальное дерево более обобщенным образом. (Вы можете теоретически создать такое дерево с помощью родительских и дочерних свойств конкретного объекта, но вам придется точно знать, какие свойства поддерживаются, и это трудно обнаружить или управлять.)

Обычно вы объединяете несколько вызовов API VisualTreeHelper для записи собственных вспомогательных функций, которые исследуют визуальное дерево способами, характерными для сценариев собственного приложения.

Обход визуального дерева

Обход дерева объектов (иногда известный как ходячий дерево) является распространенным методом в объектных моделях. Вы используете свойства, ссылающиеся на дочерние объекты (обычно это коллекции) или родительские связи с содержащим объектом (обычно это делается из коллекции и возвращает саму коллекцию). В качестве грубого описания процесса вызывается последовательность дочерних свойств и родительских свойств или, возможно, вспомогательных методов, чтобы перемещаться по осям дерева объектов, пока не вы получите значение, содержащее объект, который вы искали. Как правило, вы должны иметь возможность создавать содержимое в XAML таким образом, чтобы не нужно запрашивать структуру дерева. Чтобы избежать необходимости обхода дерева, следует предоставить элементам XAML значение атрибута x:Name / в разметке XAML, создающей их. Это создает немедленную ссылку, доступную для доступа к коду во время выполнения, и это гораздо менее подверженная ошибкам методика получения ссылок на объекты, чем ходьба по дереву. Кроме того, если вы создаете объекты с помощью кода, а не XAML, следует объявить частные поля или переменные, которые сохраняют ссылку на объекты во время выполнения. Обычно нет необходимости проходить по дереву, чтобы найти объекты, созданные в собственном коде.

Однако существуют случаи, когда невозможно или практически дать объекту имя и сохранить ссылку на объект в области. Один из таких сценариев заключается в добавлении динамического содержимого, предоставленного пользователем или предоставленным привязкой данных, или использовании моделей представления и бизнес-объектов. В таких случаях нельзя всегда прогнозировать количество добавленных элементов или структуру элемента управления и его дочерних элементов. Другой сценарий — изучение примененного шаблона для элемента управления или составного раздела содержимого элемента управления или докладчика.

Обход дерева вниз (вдали от корня) можно выполнить с помощью GetChildrenCount для ненулевых значений, а затем GetChild для запроса определенного индекса. Возможно, вам придется использовать методы try/catch или эквивалентные, если вы пытаетесь привести элементы в качестве определенных подтипов UIElement . Как правило, API VisualTreeHelper возвращает элементы в качестве DependencyObject , и вам потребуется привести его для выполнения каких-либо полезных действий (даже для простой операции, как проверка значения имени ).

Методы

Имя Описание
DisconnectChildrenRecursive(UIElement)

Явным образом удаляет все ссылки из целевого UIElement с целью очистки циклов ссылок.

FindElementsInHostCoordinates(Point, UIElement, Boolean)

Извлекает набор объектов, расположенных в указанной точке координат x-y пользовательского интерфейса приложения. Набор объектов представляет компоненты визуального дерева, совместно использующего этот момент.

FindElementsInHostCoordinates(Point, UIElement)

Извлекает набор объектов, расположенных в указанной точке координат x-y пользовательского интерфейса приложения. Набор объектов представляет компоненты визуального дерева, совместно использующего этот момент.

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

Извлекает набор объектов, расположенных в заданном кадре прямоугольника пользовательского интерфейса приложения. Набор объектов представляет компоненты визуального дерева, которые совместно используют прямоугольную область, и могут включать элементы, которые перерисовываются.

FindElementsInHostCoordinates(Rect, UIElement)

Извлекает набор объектов, расположенных в заданном кадре прямоугольника пользовательского интерфейса приложения. Набор объектов представляет компоненты визуального дерева, которые совместно используют прямоугольную область, и могут включать элементы, которые перерисовываются.

GetChild(DependencyObject, Int32)

Используя предоставленный индекс, получает конкретный дочерний объект предоставленного объекта, проверяя визуальное дерево.

GetChildrenCount(DependencyObject)

Возвращает количество дочерних элементов, существующих в дочерней коллекции объекта в визуальном дереве.

GetOpenPopups(Window)

Извлекает коллекцию всех открытых элементов управления всплывающего окна из целевого окна.

GetOpenPopupsForXamlRoot(XamlRoot)

Извлекает коллекцию всех открытых элементов управления всплывающего окна из целевого объекта XamlRoot.

GetParent(DependencyObject)

Возвращает родительский объект объекта в визуальном дереве.

Применяется к

См. также раздел