Dynamo 3.6.2 Data-Shape TreeView input node blank...?

Using a simple test graph:

Anyone else having this issue?

I have installed only PythonNet3 Engine (no IronPython, or Python version 2.x)…

Data-Shape 2026.4.2

here is a code fix for TreeView input node

# Copyright (c) Data Shapes, 2025
# Data-Shapes www.data-shapes.io, elayoubi.mostafa@data-shapes.io @data_shapes

import clr
import unicodedata

try:
    clr.AddReference("System.Windows.Forms")
    clr.AddReference("System.Drawing")
    clr.AddReference("PresentationCore")
    clr.AddReference("WindowsBase")
    from System.Windows.Forms import TreeView, TreeNode, MouseButtons
    from System.Drawing import Point
    from System.Windows.Input import Key, Keyboard
except Exception:
    TreeView = None
    TreeNode = None
    MouseButtons = None
    Point = None
    Key = None
    Keyboard = None


class uitreeview(object):

    def __init__(self, inputname="", datalist=None, hastitles=False, height=200):
        self.inputname = inputname if inputname is not None else ""
        self.datalist = datalist if datalist is not None else []
        self._hastitles = bool(hastitles)
        self._height = height if isinstance(height, (int, float)) else 0
        self._input_type = "uitreeview"

    def __repr__(self):
        return "UI.TreeView input"

    def build_treeview(self, formbody, xlabel, xinput, y, xRatio, yRatio):
        if TreeView is None:
            return None, y

        tv = TreeView()
        tv.CheckBoxes = True

        # Size and placement
        if self.inputname != "":
            tv.Width = int(formbody.Width - 25 * xRatio - xinput)
            tv.Location = Point(int(xinput), int(y))
        else:
            tv.Width = int(formbody.Width - 25 * xRatio - xlabel)
            tv.Location = Point(int(xlabel), int(y))
        tv.Height = int(self._height * yRatio)

        # Populate nodes
        root = TreeNode("List1")
        tv.Nodes.Add(root)

        def _build_nodes():
            data_list = self._ensure_list(self.datalist)
            if self._hastitles:
                for dl in data_list:
                    self._tree_iteration_title(root, dl)
            else:
                for dl in data_list:
                    self._tree_iteration(root, dl)

        try:
            _build_nodes()
        except Exception:
            # simple fallback: add each item as a leaf
            try:
                for item in self._ensure_list(self.datalist):
                    leaf = TreeNode(self._remove_accents(self._stringify(item)))
                    leaf.Tag = item
                    root.Nodes.Add(leaf)
            except Exception:
                pass

        root.Expand()
        try:
            tv.ExpandAll()
        except Exception:
            pass

        # Attach handlers
        start_node = {"node": None}

        def _tree_node_mouse_down(sender, event):
            try:
                if (
                    Keyboard is not None
                    and Key is not None
                    and event.Button == MouseButtons.Left
                    and Keyboard.IsKeyDown(Key.LeftShift)
                ):
                    tv_local = sender
                    end_node = tv_local.GetNodeAt(0, event.Y)
                    if (
                        start_node["node"] is not None
                        and end_node is not None
                        and start_node["node"].Parent == end_node.Parent
                    ):
                        start_idx = start_node["node"].Index
                        end_idx = end_node.Index
                        if start_idx > end_idx:
                            start_idx, end_idx = end_idx, start_idx
                        for i in range(start_idx, end_idx + 1):
                            current = start_node["node"].Parent.Nodes[i]
                            current.Checked = not current.Checked
                    return
                start_node["node"] = sender.GetNodeAt(0, event.Y)
            except Exception:
                start_node["node"] = None

        def _check_children(sender, event):
            try:
                ev_node = event.Node
                check_state = ev_node.Checked
                for n in ev_node.Nodes:
                    n.Checked = check_state
            except Exception:
                pass

        if Keyboard is not None and MouseButtons is not None:
            tv.MouseDown += _tree_node_mouse_down
        tv.AfterCheck += _check_children

        def _gather_checked(node, acc):
            try:
                if node.Nodes is not None and node.Nodes.Count > 0:
                    for child in node.Nodes:
                        _gather_checked(child, acc)
                else:
                    if getattr(node, "Checked", False):
                        acc.append(getattr(node, "Tag", None))
            except Exception:
                pass

        def _get_checked_values():
            checked = []
            try:
                if tv.Nodes.Count > 0:
                    _gather_checked(tv.Nodes[0], checked)
            except Exception:
                pass
            return checked

        # Store getter for the form to consume on close
        tv.Tag = _get_checked_values
        formbody.Controls.Add(tv) # BUG FIX HERE

        next_y = tv.Bottom + int(25 * yRatio)
        return tv, next_y

    def _tree_iteration_title(self, control, input_val):
        if isinstance(input_val, list):
            data_copy = list(input_val)
            try:
                title = data_copy.pop(0)
            except Exception:
                title = None
            node_text = self._stringify(title) if title is not None else "{0}.{1}".format(
                control.Text, len(control.Nodes) + 1
            )
            node_text = self._remove_accents(node_text)
            current_node = TreeNode(node_text)
            current_node.Tag = ""
            control.Nodes.Add(current_node)
            for item in data_copy:
                self._tree_iteration_title(current_node, item)
        else:
            item_node = TreeNode(self._remove_accents(self._stringify(input_val)))
            item_node.Tag = input_val
            control.Nodes.Add(item_node)

    def _tree_iteration(self, control, input_val):
        if isinstance(input_val, list):
            current_node = TreeNode("{0}.{1}".format(control.Text, len(control.Nodes) + 1))
            current_node.Tag = input_val
            control.Nodes.Add(current_node)
            for item in input_val:
                self._tree_iteration(current_node, item)
        else:
            item_node = TreeNode(self._remove_accents(self._stringify(input_val)))
            item_node.Tag = input_val
            control.Nodes.Add(item_node)

    def _stringify(self, obj):
        try:
            return str(obj)
        except Exception:
            try:
                return obj.encode("utf-8").decode("utf-8")
            except Exception:
                return ""

    def _remove_accents(self, input_str):
        nfkd_form = unicodedata.normalize("NFKD", str(input_str))
        only_ascii = nfkd_form.encode("ASCII", "ignore")
        return only_ascii.decode("ASCII")

    def _ensure_list(self, obj):
        if obj is None:
            return []
        if isinstance(obj, list):
            return obj
        try:
            return list(obj)
        except Exception:
            return [obj]


inputname = IN[0] if len(IN) > 0 else ""
datalist = IN[1] if len(IN) > 1 else []
hastitles = IN[2] if len(IN) > 2 else False
height = IN[3] if len(IN) > 3 else 150

OUT = uitreeview(inputname, datalist, hastitles, height)

FYI @mostafa.elayoubi.ds

Thank you, this worked!