TreeView
Используйте TreeView для отображения иерархических данных в деревообразной структуре. Это мощный и гибкий контроллер, который обычно используется для представления данных с родительско-дочерними отношениями или вложенными структурами.
Если вам нужен простой список элементов (а не иерархическое дерево), рассмотрите возможность использования контроля ListView.
Создать TreeView
Вы можете создать TreeView с UI Builder, UXML и C#. Следующий пример C# создает TreeView:
var treeView = new TreeView();
Обновить представление коллекции
Чтобы обновить представление коллекции, вы можете вызвать либо RefreshItems/RefreshItem или Rebuild.
Как правило, вызов метода RefreshItems или RefreshItem — эти методы обновляют только представление коллекции и менее дорогостоящи. Если вызов метода Rebuild, представление коллекции полностью перестроено, что может быть дорогостоящим.
Однако вы должны вызвать Rebuild в следующих случаях:
- Вы меняете тип источник данных, например при переходе от
List<float>к аList<Vector3>. - Вы изменяете
makeItemилиdestroyItem.
Привязать TreeView к данным
Вы можете связать TreeView с источником данных. Источником данных может быть список объектов или список строк.
Следующий пример связывает TreeView с пользовательским типом.
treeView.makeItem = () => new VisualElement();
var item = new VisualElement();
treeView.bindItem = (item, i) =>
{
var c = treeView.GetItemDataForIndex<MyCustomType>(i);
};
ПримечаниеВ предыдущем примере TreeView.bindItem Индекс. Вы должны использовать Индекс (а не ID) с GetItemDataForIndex<T>.
Реализация операций перетаскивания для TreeView
Перетаскивание — распространённый приём в проектировании интерфейсов. Чтобы реализовать операции перетаскивания, переопределите следующие методы:
- Чтобы включить перетаскивание элементов, переопределите
canStartDrag. - Чтобы задать, какие элементы перетаскиваются, переопределите
setupDragAndDrop. - Чтобы получать изменения статуса элементов, переопределите
dragAndDropUpdate. Вы можете выполнять определенные действия на основе положения перетаскивания или других условий. - Чтобы управлять поведением перетаскивания, переопределите
handleDrop.
Во время операции перетаскивания вы можете включить перестановку элементов путем перетаскивания. Чтобы включить эту функцию, установите атрибут reorderable на true в UI Builder, UXML и C#.
См. Создание списка перетаскивания и дерева представлений между окнами для примера.
Настройка иерархии TreeView
Чтобы установить иерархию TreeView, объявьте TreeViewItemData<T>, где T является типом данных для дерева, а затем установите источник через SetRootItems API.. Например, предположим, что у вас есть следующая структура UXML:
<UXML xmlns="UnityEngine.UIElements">
<TreeView class="the-uxml-treeview" fixed-item-height="20" />
</UXML>
Следующий пример USS стилизует TreeView:
.the-uxml-treeview {
height: 200px;
}
.unity-tree-view__item-content > .unity-label {
flex-grow: 1;
margin-top: 2px;
}
Вы можете настроить иерархию TreeView следующим образом:
var treeView = container.Q<TreeView>();
// Create some list of data, here simply numbers in a few foldouts
var items = new List<TreeViewItemData<string>>(10);
for (var i = 0; i < 10; i++)
{
var itemIndex = i * 10 + i;
var treeViewSubItemsData = new List<TreeViewItemData<string>>(10);
for (var j = 0; j < 10; j++)
treeViewSubItemsData.Add(new TreeViewItemData<string>(itemIndex + j + 1, $"Data {i+1}-{j+1}"));
var treeViewItemData = new TreeViewItemData<string>(itemIndex, $"Data {i+1}", treeViewSubItemsData);
items.Add(treeViewItemData);
};
// The "makeItem" function will be called as needed
// when the TreeView needs more items to render
Func<VisualElement> makeItem = () => new Label();
// As the user scrolls through the list, the TreeView object
// will recycle elements created by the "makeItem"
// and invoke the "bindItem" callback to associate
// the element with the matching data item (specified as an index in the list)
Action<VisualElement, int> bindItem = (e, i) =>
{
var item = treeView.GetItemDataForIndex<string>(i);
var id = treeView.GetIdForIndex(i);
((Label)e).text = $"ID {id} - {item}";
};
treeView.SetRootItems(items);
treeView.makeItem = makeItem;
treeView.bindItem = bindItem;
treeView.selectionType = SelectionType.Multiple;
treeView.Rebuild();
// Callback invoked when the user double clicks an item
treeView.itemsChosen += (selectedItems) =>
{
Debug.Log("Items chosen: " + string.Join(", ", selectedItems));
};
// Callback invoked when the user changes the selection inside the TreeView
treeView.selectedIndicesChanged += (selectedIndices) =>
{
var log = "IDs selected: ";
foreach (var index in selectedIndices)
{
log += $"{treeView.GetIdForIndex(index)}, ";
}
Debug.Log(log.TrimEnd(',', ' '));
};
Чтобы попробовать этот пример в Unity, перейдите в Окно > UI Toolkit > Образцы.
TreeView FAQs
Ниже приведены некоторые часто задаваемые вопросы об управлении TreeView:
Могу ли я получить список строк, которые видны в представлении?
Для этого нет выделенных APIs. Вы можете использовать UQuery для получения интересующих элементов.
Обязательно ли для любой из переопределенных функций контроллера вида вызывать base.Method?
Вызывайте этот метод только в том случае, если требуется расширить его поведение по умолчанию.
Я добавил Toggle в мою строку. Почему выбор не переходит в эту строку, когда пользователь выбирает его?
По умолчанию, строка выбирается только в том случае, если событие нажатия мыши не потребляется содержимым строки. В этом случае ваш Toggle останавливает распространение события. Чтобы исправить это, зарегистрируйте обратный вызов PointerDownEvent с TrickleDown на Toggle, чтобы вызвать SetSelection.
Как получить обратный вызов, когда пользователь изменяет свой выбор в представлении?
Рекомендуется использовать обратный вызов selectedIndicesChanged для получения данных по индексу, когда это необходимо. Хотя вы также можете использовать selectionChanged, помните, что он возвращает список объектов, что может привести к выделению блоков при использовании с типами значений.
Могу ли я получить индексы строк, которые видны на экране?
Для этого нет выделенного APIs. Вы можете использовать обратные вызова bindItem и unbindItem для отслеживания этих индексов в userData.
Как преобразовать ID в индекс и наоборот?
Используйте BaseTreeViewController.GetIndexForId и BaseTreeViewController.GetIdForIndex.
Могу ли я иметь горизонтальный TreeView?
Контроллер TreeView не поддерживает горизонтальное расположение и виртуализацию. Рекомендуется использовать ScrollView с flex-direction: row для горизонтального расположения элементов.
Примеры
- Создание представлений списка и дерева: Используйте ListView, TreeView, MultiColumnListView и MultiColumnTreeView для создания представлений списка и дерева.
- Создание перетаскиваемого списка и дерева представлений между окнами: Используйте ListView, TreeView и MultiColumnListView для создания перетаскиваемого UI между окнами.
Базовый класс C# и пространство имён
C# класс: TreeView
Пространство имен: UnityEngine.UIElements
Базовый класс: BaseTreeView
Атрибуты члена UXML
Этот элемент имеет следующие атрибуты члена:
| Имя | Тип | Описание |
|---|---|---|
item-template |
UIElements.VisualTreeAsset |
Шаблон UXML, который конструирует каждый переработанный и отброшенный элемент в дереве. Этот шаблон предназначен для замены определения makeItem. |
Унаследованные атрибуты UXML
Этот элемент наследует от своего базового класса следующие атрибуты:
| Имя | Тип | Описание |
|---|---|---|
auto-expand |
boolean |
Если true, элементы автоматически разворачиваются при добавлении в TreeView. |
binding-path |
string |
Путь к целевому свойству для привязки. |
fixed-item-height |
float |
Высота отдельного элемента в списке, в пикселях. Это свойство должно быть установлено при использовании virtualizationMethod, значением которого является FixedHeight, для того, чтобы функционировало представление коллекции. Если это свойство установлено, когда virtualizationMethod является DynamicHeight, оно служит высотой по умолчанию для вычисления необходимого количества элементов и области прокрутки, прежде чем элементы будут расположены. Его следует установить на минимальную ожидаемую высоту элемента. |
focusable |
boolean |
Если false, то элемент не может быть фокусирован. Элемент может быть фокусирован только в том случае, если его свойство canGrabFocus имеет значение true. |
horizontal-scrolling |
boolean |
Это свойство определяет, показывает ли представление коллекции горизонтальную панель прокрутки, когда ее содержимое не вписывается в видимую область. |
reorderable |
boolean |
Получает или устанавливает значение, указывающее, может ли пользователь перетаскивать элементы списка для изменения их порядка. Значение по умолчанию — false, которое позволяет пользователю перетаскивать элементы в другие представления и из них при реализации canStartDrag, setupDragAndDrop, dragAndDropUpdateи handleDrop. Установите это значение на true, чтобы разрешить пользователю изменять порядок элементов в списке. |
selection-type |
UIElements.SelectionType |
Управляет типом выбора. Значение по умолчанию — SelectionType.Single. При отключении выбора в представлении коллекции любой текущий выбор удаляется. |
show-alternating-row-backgrounds |
UIElements.AlternatingRowBackground |
Это свойство определяет, будут ли цвета фона строк представления коллекции чередоваться. AlternatingRowBackground enum. |
show-border |
boolean |
Включите это свойство для отображения границы вокруг представления коллекции. Если установлено значение true, то вокруг ScrollView, используемого внутри представления коллекции, отображается граница. |
tabindex |
int |
Целое число, используемое для сортировки фокусируемых элементов в кольце фокуса. Должно быть больше или равно нулю. Установка значения tabIndex меньше 0 (например, −1) удаляет элемент из кольца фокуса и навигации по вкладкам. |
virtualization-method |
UIElements.CollectionVirtualizationMethod |
Метод виртуализации, который будет использоваться для этой коллекции, когда видна полоса прокрутки. Принимает значение из CollectionVirtualizationMethod enum.Значение по умолчанию FixedHeight. При использовании фиксированной высоты указать fixedItemHeight Фиксированная высота более эффективна, но предлагает меньше гибкости в отношении содержания. DynamicHeight, коллекция будет ждать вычисления фактической высоты. Динамическая высота более гибкая, но менее эффективная. |
Этот элемент также наследует следующие атрибуты от VisualElement:
| Имя | Тип | Описание |
|---|---|---|
content-container |
string |
Логический контейнер, в который добавляются дочерние элементы. Если к этому элементу добавляется дочерний элемент, то он добавляется в контейнер содержимого этого элемента. При итерации над VisualElement.Children При использовании элемента вместо самого элемента используется иерархия контейнера содержимого элемента. Это может привести к неожиданным результатам, например, к игнорированию элементов событиями навигации, если они не находятся непосредственно в иерархической структуре контейнера. См. IFocusRing для больше информации.Если контейнер содержимого совпадает с самим элементом, то дочерние элементы добавляются непосредственно к элементу. Это верно для большинства элементов, но может быть переопределено более сложными типами. ScrollView, например, имеет контейнер содержимого, отличающийся от самого себя. В этом случае дочерние элементы, добавленные к представлению прокрутки, добавляются вместо этого к его элементу контейнера содержа-VisualElement.Hierarchy.parent) дочерних элементов является элементом контейнера содержимого прокрутки, их логическим родителем (VisualElement.parentПоскольку некоторые фокусируемые дочерние объекты представления прокрутки не являются частью его логической иерархии, такие как его Scroller элементов, эти фокусируемые дочерние элементы не рассматриваются по умолчанию при использовании последовательной навигации. Как я могу изменить, какой элемент будет фокусироваться дальше для примера решения, если правила навигации по умолчанию не соответствуют вашим потребностям. |
data-source |
Object |
Назначает источник данных этому VisualElement, который переопределяет любой унаследованный источник данных. Этот источник данных наследуется всеми дочерними объектами. |
data-source-path |
string |
Путь от источника данных к значению. |
data-source-type |
System.Type |
Возможный тип источника данных, присваиваемый этому VisualElement. Эта информация используется UI Builder только как подсказка для определенного заполнения поля пути источника данных, когда эффективный источник данных не может быть указан во время проектирования. |
enabled |
boolean |
Возвращает true, если VisualElement разрешен локально.Этот флаг не изменяется, если VisualElement имплицитно отключен одним из родителей. Чтобы проверить это, используйте enabledInHierarchy. |
language-direction |
UIElements.LanguageDirection |
Указывает направленность текста элемента. Значение будет распространяться на дочерей элемента. Установка languageDirection на RTL может получить только базовую поддержку RTL, такую как инверсия текста. Чтобы получить более полную поддержку RTL, такую как перерыв строки, перенос слов или формирование текста, вы должны включить Усовершенствованный текстовый генератор. |
name |
string |
Имя этого VisualElement. Используйте это свойство для написания селекторов USS, которые нацелены на определенный элемент. Стандартная практика заключается в том, чтобы дать элементу уникальное имя. |
picking-mode |
UIElements.PickingMode |
Определяет, может ли этот элемент быть целью событий указателя или выбран IPanel.Pick запросов.Элементы не могут быть выбраны, если: - Они невидимы. style.display установлен на DisplayStyle.NoneЭлементы с режимом подбора PickingMode.Ignore никогда не получать псевдо-state. |
style |
string |
Задает значения стиля на VisualElement.Возвращаемые данные стиля, рассчитанные из USS файлы или встроенные стили, записанные в этот объект в C#, не представляет полностью разрешенные стили, такие как окончательная высота и ширина VisualElement. Чтобы получить доступ к этим полностью разрешенным стилям, используйте resolvedStyle.Дополнительные сведения об использовании этого свойства и всех поддерживаемых USS свойства, см. Применить стили в C# сценарии и USS ссылка на свойства страницы руководства. |
tooltip |
string |
Текст, который будет отображаться внутри информационного поля после того, как пользователь задержится над элементом небольшое время. Это поддерживается только в Редакторе UI. |
usage-hints |
UIElements.UsageHints |
Комбинация значений подсказки, которые указывают высокоуровневые предполагаемые схемы использования для VisualElement. Это свойство может быть установлено только тогда, когда VisualElement еще не является частью Panel. Как только оно становится частью Panel, это свойство становится эффективно только для чтения, и попытки изменить его будут вызывать исключение. Указание правильного UsageHints заставляет систему принимать более правильные решения о том, как обрабатывать или ускорять определенные операции на основе предполагаемой схемы использования. Обратите внимание, что эти подсказки не влияют на поведение или визуальные результаты, а только влияют на общую производительность панели и элементов внутри нее. Рекомендуется всегда рассматривать возможность указания правильного UsageHints, но помните, что некоторые UsageHints могут быть внутренне проигнорированы при определенных условиях (e.g. из-за аппаратных ограничений на целевой платформе). |
view-data-key |
string |
Используется для устойчивости данных представления, таких как развернутые состояния дерева, положение прокрутки или уровень масштаба. Этот ключ используется для сохранения и загрузки данных представления из хранилища данных представления. Если этот ключ не установлен, устойчивость отключена для связанного VisualElement. Дополнительные сведения см. в разделе Устойчивость данных представления в руководстве Unity. |
Классы USS
В таблице ниже перечислены все открытые имена свойств C# и связанные с ними селекторы USS.
| C# собственность | USS выбор | Описание |
|---|---|---|
ussClassName |
.unity-tree-view |
Имя USS-класса для элементов TreeView. Unity добавляет этот USS-класс к каждому экземпляру элемента TreeView. Любые стили, применённые к этому классу, влияют на все TreeView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemUssClassName |
.unity-tree-view__item |
Имя USS-класса для элементов списка TreeView. Unity добавляет этот USS-класс к каждому элементу списка в TreeView. Любые стили, применённые к этому классу, влияют на все элементы, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemToggleUssClassName |
.unity-tree-view__item-toggle |
Имя USS-класса для элементов-переключателей списка TreeView. Unity добавляет этот USS-класс к каждому элементу-переключателю в TreeView. Любые стили, применённые к этому классу, влияют на все элементы, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemIndentsContainerUssClassName |
.unity-tree-view__item-indents |
Имя USS-класса для элементов-контейнеров отступа TreeView. Unity добавляет этот USS-класс к каждому элементу-контейнеру отступа в TreeView. Любые стили, применённые к этому классу, влияют на все элементы, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemIndentUssClassName |
.unity-tree-view__item-indent |
Имя USS-класса для элемента отступа TreeView. Unity добавляет этот USS-класс к каждому элементу отступа в TreeView. Любые стили, применённые к этому классу, влияют на все элементы, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemContentContainerUssClassName |
.unity-tree-view__item-content |
Имя USS-класса для элементов-контейнеров списка TreeView. Unity добавляет этот USS-класс к каждому элементу-контейнеру элементов в TreeView. Любые стили, применённые к этому классу, влияют на все элементы, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
ussClassName |
.unity-collection-view |
Имя USS-класса для элементов BaseVerticalCollectionView. Unity добавляет этот USS-класс к каждому экземпляру элемента BaseVerticalCollectionView. Любые стили, применённые к этому классу, влияют на все BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
borderUssClassName |
.unity-collection-view--with-border |
Имя USS-класса для элементов BaseVerticalCollectionView с рамкой. Unity добавляет этот USS-класс к экземпляру элемента BaseVerticalCollectionView, если у этого экземпляра свойство BaseVerticalCollectionView.showBorder имеет значение true. Любые стили, применённые к этому классу, влияют на все такие BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemUssClassName |
.unity-collection-view__item |
Имя USS-класса для элементов списка в элементах BaseVerticalCollectionView. Unity добавляет этот USS-класс к каждому элементу списка, содержащемуся в BaseVerticalCollectionView. Любые стили, применённые к этому классу, влияют на все элементы списка, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
dragHoverBarUssClassName |
.unity-collection-view__drag-hover-bar |
Имя USS-класса для полосы наведения при перетаскивании. Unity добавляет этот USS-класс к полосе, которая появляется, когда пользователь перетаскивает элемент списка. Любые стили, применённые к этому классу, влияют на все элементы BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
dragHoverMarkerUssClassName |
.unity-collection-view__drag-hover-marker |
Имя USS-класса для круглого маркера наведения при перетаскивании, обозначающего глубину. Unity добавляет этот USS-класс к полосе, которая появляется, когда пользователь перетаскивает элемент списка. Любые стили, применённые к этому классу, влияют на все элементы BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemDragHoverUssClassName |
.unity-collection-view__item--drag-hover |
Имя USS-класса, применяемое к элементу списка при наведении перетаскиваемого объекта. Unity добавляет этот USS-класс к элементу списка, когда его перетаскивают. Любые стили, применённые к этому классу, влияют на все элементы BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemSelectedVariantUssClassName |
.unity-collection-view__item--selected |
Имя USS-класса для выбранных элементов списка в BaseVerticalCollectionView. Unity добавляет этот USS-класс к каждому выбранному элементу в BaseVerticalCollectionView. Свойство BaseVerticalCollectionView.selectionType определяет, можно ли выбрать ноль, один или несколько элементов. Любые стили, применённые к этому классу, влияют на все элементы BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
itemAlternativeBackgroundUssClassName |
.unity-collection-view__item--alternative-background |
Имя USS-класса для нечётных строк в BaseVerticalCollectionView. Unity добавляет этот USS-класс к каждому нечётному элементу в BaseVerticalCollectionView, когда свойство BaseVerticalCollectionView.showAlternatingRowBackgrounds свойство установлено на ContentOnly или All. Когда showAlternatingRowBackgrounds имеет одно из этих значений, нечётные элементы отображаются с иным цветом фона, чем чётные. Этот USS-класс служит для того, чтобы отличать нечётные элементы от чётных. Когда свойство showAlternatingRowBackgrounds свойство установлено на None, USS-класс не добавляется, и любые стили или поведение, которые на него опираются, становятся недействительными. |
listScrollViewUssClassName |
.unity-collection-view__scroll-view |
Имя USS-класса для области прокрутки в BaseVerticalCollectionView. Unity добавляет этот USS-класс к области прокрутки BaseVerticalCollectionView. Любые стили, применённые к этому классу, влияют на все области прокрутки BaseVerticalCollectionView, расположенные рядом с таблицей стилей или ниже неё в визуальном дереве. |
disabledUssClassName |
.unity-disabled |
Имя USS-класса для локально отключённых элементов. |
Вы также можете использовать раздел Соответствующие селекторы в отладчике Inspector или UI Toolkit, чтобы увидеть, какие селекторы USS влияют на компоненты VisualElement на каждом уровне его иерархии.