TreeView

  • All collections support virtualization: gameobjects will be created only for visible items.
  • Add Selectable component to use keyboard and gamepad navigation.

Attention

Different TreeView’s cannot display same nodes, unlike ListView, TileView, and Table.

Get nodes

public TreeView Tree;

ObservableList<TreeNode<TreeViewItem>> nodes;

void Start()
{
   nodes = Tree.Nodes;
}

Get selected nodes

Tree.SelectedNodes.ForEach(x =>
{
   // do something with selected node
   Debug.Log(x.Item.Name);

   var component = Tree.GetItemComponent(x.Index);

   // not displayed component will be null
   if (component != null)
   {
      component.DoSomething();
   }
});

Add listeners

void AddListeners()
{
   Tree.NodeSelected.AddListener(ProcessSelectedNode);

   Tree.NodeDeselected.AddListener(ProcessDeselectedNode);
}

void ProcessSelectedNode(TreeNode<TreeViewItem> node)
{
   Debug.Log("selected: " + node.Item.Name);
}

void void ProcessDeselectedNode(TreeNode<TreeViewItem> node)
{
   Debug.Log("deselected: " + node.Item.Name);
}

Select node

Tree.SelectNode(nodes[1].Nodes[0]);

Select node with subnodes

Tree.SelectNodeWithSubnodes(nodes[1].Nodes[1]);

Deselect node

Tree.DeselectNode(nodes[1].Nodes[0]);

Deselect node with subnodes

Tree.DeselectNodeWithSubnodes(nodes[1].Nodes[1]);

Scroll to node

Tree.ScrollToAnimated(node);

Add node

var test_item = new TreeViewItem("added");
var test_node = new TreeNode<TreeViewItem>(test_item);
nodes.Add(test_node);

Hide nodes

nodes[1].IsVisible = false;
nodes[2].Nodes[1].IsVisible = false;

Collapse node

nodes[0].Nodes[0].IsExpanded = false;

Expand node

nodes[0].Nodes[0].IsExpanded = true;

Change node name

nodes[0].Item.Name = "Node renamed from code";
nodes[0].Nodes[1].Item.Name = "Another node renamed from code";

Sort

// Compare nodes by Name in ascending order
Comparison<TreeNode<TreeViewItem>> comparisonAsc = (x, y) => x.Item.Name.CompareTo(y.Item.Name);

// Compare nodes by Name in descending order
Comparison<TreeNode<TreeViewItem>> comparisonDesc = (x, y) => -x.Item.Name.CompareTo(y.Item.Name);

public void SortAsc()
{
   nodes.BeginUpdate();
   ApplyNodesSort(nodes, comparisonAsc);
   nodes.EndUpdate();
}

public void SortDesc()
{
   nodes.BeginUpdate();
   ApplyNodesSort(nodes, comparisonDesc);
   nodes.EndUpdate();
}

void ApplyNodesSort<T>(ObservableList<TreeNode<T>> nodes, Comparison<TreeNode<T>> comparison)
{
   // apply sort for current nodes
   nodes.Sort(comparison);
   // apply sort for child nodes
   nodes.ForEach(node =>
   {
      if (node.Nodes != null)
      {
         ApplyNodesSort(node.Nodes as ObservableList<TreeNode<T>>, comparison);
      }
   });
}

Filter nodes

public void Filter(string nameContains)
{
   // Maintains performance while items are added/removed/changed
   // by preventing the widgets from drawing
   // until the EndUpdate() method is called.
   nodes.BeginUpdate();

   SampleFilter(nodes, x => x.Name.Contains(nameContains));

   // Apply changes.
   nodes.EndUpdate();
}

bool SampleFilter(IObservableList<TreeNode<TreeViewItem>> nodes, Func<TreeViewItem,bool> filterFunc)
{
   return nodes.Count(x =>
   {
      var have_visible_children = (x.Nodes==null) ? false : SampleFilter(x.Nodes, filterFunc);
      x.IsVisible = have_visible_children || filterFunc(x.Item);
      return x.IsVisible;
   }) > 0;
}

Reset filter

public void ResetFilter()
{
   nodes.BeginUpdate();
   nodes.ForEach(SetVisible);
   nodes.EndUpdate();
}

void SetVisible(TreeNode<TreeViewItem> node)
{
   if (node.Nodes != null)
   {
      node.Nodes.ForEach(SetVisible);
   }

   node.IsVisible = true;
}

Clear nodes

public void Clear()
{
   nodes.Clear();
}