перемещаться по всем элементам в дереве WPF

Я хочу иметь возможность перемещаться по дереву визуального пользовательского интерфейса в поисках элемента с идентификатором, привязанным к свойству Tag визуального элемента.

Мне интересно, как я это делаю. У элементов управления нет дочерних элементов для перемещения.

Я начал использовать LogicalTreeHelper.GetChildren, который, кажется, работает по назначению, пока я не нажал на элемент управления TreeView ... тогда LogicalTreeHelper.GetChildren не возвращает никаких дочерних элементов.

Примечание: цель состоит в том, чтобы найти визуальный элемент пользовательского интерфейса, соответствующий элементу данных. То есть, учитывая идентификатор элемента, Go найдите элемент пользовательского интерфейса, отображающий его.

Изменить: я, по-видимому, недостаточно хорошо это объясняю. Я привязываю некоторые объекты данных к элементу управления TreeView, а затем хочу программно выбрать конкретный элемент с учетом идентификатора этого бизнес-объекта. Я не понимаю, почему так сложно обойти визуальное дерево и найти нужный мне элемент, поскольку идентификатор объекта данных находится в свойстве Tag соответствующего визуального элемента. Я использую Mole и могу найти элемент пользовательского интерфейса с соответствующим идентификатором в его теге. Я просто не могу найти визуальный элемент в коде. LogicalTreeHelper не просматривает никакие элементы в дереве. ItemContainerGenerator.ContainerFromItem также не извлекает ничего для элементов в древовидном представлении.


person Brian Leahy    schedule 03.04.2009    source источник


Ответы (4)


Взгляните на этот образец. Я нашел этот образец очень хорошо написанным и считаю, что использование модели представления решит вашу проблему.

Редактировать: А по поводу поиска по визуальному дереву. И TreeView, и TreeViewItem имеют свойство Items, по которому вы можете перемещаться и искать свой идентификатор. Разве ты не можешь его использовать?

person Yuval Peled    schedule 06.04.2009
comment
Свойство items - это не визуальные элементы данных. Затем я могу получить элемент данных и запросить соответствующий визуальный элемент, затем мне нужно пройтись по свойству Items визуального элемента, которое является элементами данных. Это не работает, я просто хочу пройтись по визуальному дереву ... так неубедительно - person Brian Leahy; 08.04.2009

Проблема в том, что были созданы только видимые TreeViewItems - WPF не создает все элементы заранее (из-за продолжительности времени, которое может потребоваться для больших деревьев, я полагаю).

Лучшим подходом было бы создать структуру данных, которая имитирует структуру данных вашего дерева, и использовать привязку данных, чтобы сообщить TreeView, как отображать эти данные. Если хотите, я могу написать простой пример.

РЕДАКТИРОВАТЬ: на основе вашего редактирования это будет работать только в том случае, если для этого объекта был создан элемент пользовательского интерфейса, что не гарантируется. Взгляните на интерфейс IItemContainerGenerator ( извлекается путем вызова ItemsControl.ItemContainerGenerator Я считаю, что у него есть метод, который вернет контейнер пользовательского интерфейса (т.е. TreeViewItem) для заданного объекта данных. Он будет работать только в том случае, если контейнер пользовательского интерфейса был ранее создан.

person Andy    schedule 03.04.2009
comment
Основываясь на моей работе с TreeView, я понял, как это работает. Для узлов дерева нет визуального дерева. Они создаются по запросу по мере необходимости. Следовательно, невозможно надежно перемещаться по визуальному дереву. - person Peter Stephens; 17.11.2009

LogicalTreeHelper.GetChildren проверяет свойство LogicalChildren элемента управления, которое по умолчанию имеет значение NULL для TreeView (производного от класса ItemsControl). Возможно, вам придется проверить тип объектов, возвращаемых GetChildren, и, когда вы перейдете к объекту TreeView, выполнить некоторую особую логику обработки.

Эта особая логика, вероятно, будет перебирать элементы дерева и пытаться преобразовать их в FrameworkElement (базовый класс, определяющий свойство Tag).

person Erich Mirabal    schedule 10.04.2009

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

При работе с деревом визуалов следует помнить, что его нет, пока визуальные элементы не были загружены - вам может потребоваться присоединить делегата к событию «Loaded» вашего визуального элемента, если визуальный элемент еще не был отрисован в точка, которую вы называете кодом.

person Guy Starbuck    schedule 10.04.2009
comment
Мертвая ссылка {что-то неважное, просто чтобы понять длину комментария}. - person greenoldman; 03.01.2011
comment
Хорошо, обновлено - спасибо за предупреждение, похоже, блоггер изменил свой движок блога. - person Guy Starbuck; 04.01.2011