навигация по всем элементам в древовидном представлении wpf

StackOverflow https://stackoverflow.com/questions/715883

  •  23-08-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Нет правильного решения

Другие советы

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top