ETO, Python: GridView.DataStore is not populating data

I’m trying to make a table using GridView. I can’t figure out how to populate it with data. I asked Grok to make a very simple example to demonstrate the problem. The below example is what he came up with. Grok insists I need a dictionary for each row where the key is the column title. But whether I try that or just setting the gridview’s DataStore property to the list or row data, nothing displays.

What am I doing wrong?

#! python 2

import Eto.Forms
import Eto.Drawing

# Create the form
form = Eto.Forms.Dialog()
form.Title = "Fruit Table"
form.Size = Eto.Drawing.Size(600, 300)

# Create the GridView
grid_view = Eto.Forms.GridView()
grid_view.Size = Eto.Drawing.Size(550, 250)

# Define column headers
columns = ["Fruit 1", "Fruit 2", "Fruit 3"]
for col_name in columns:
    column = Eto.Forms.GridColumn()
    column.HeaderText = col_name
    column.DataCell = Eto.Forms.TextBoxCell(col_name)  # Bind to dictionary key
    column.Width = 150  # Set width for visibility
    grid_view.Columns.Add(column)

# Sample data: list of rows, each with three fruit names
data = [
    ["Apple", "Banana", "Orange"],
    ["Mango", "Pineapple", "Grape"],
    ["Kiwi", "Strawberry", "Blueberry"]
]

# Convert data to DataStore format: list of dictionaries
# this is Grok's idea and it doesn't work
grid_view.DataStore = [
    {
        "Fruit 1": row[0],
        "Fruit 2": row[1],
        "Fruit 3": row[2]
    } for row in data
]

# this is my idea, and it also doesn't work
# grid_view.DataStore = data

# Create layout and add GridView
layout = Eto.Forms.DynamicLayout()
layout.Padding = Eto.Drawing.Padding(10)
layout.Add(grid_view)

Grok figured it out. He was binding the column datacells to the column name, but if he binds it to the column index, it works. Below is the working code, the main difference is in the section where the column headers are defined. Hopefully, with this figured out, I can progress with my actual project. :slight_smile:

#! python 2

import Eto.Forms
import Eto.Drawing

# Create the form
form = Eto.Forms.Dialog()
form.Title = "Fruit Table"
form.Size = Eto.Drawing.Size(600, 300)

# Create the GridView
grid_view = Eto.Forms.GridView()
grid_view.Size = Eto.Drawing.Size(550, 250)

# Define column headers
columns = ["Fruit 1", "Fruit 2", "Fruit 3"]
for i, col_name in enumerate(columns):
    column = Eto.Forms.GridColumn()
    column.HeaderText = col_name
    column.DataCell = Eto.Forms.TextBoxCell(i)  # Bind to dictionary key
    column.Width = 150  # Set width for visibility
    grid_view.Columns.Add(column)

print(grid_view.Columns)

# Sample data: list of rows, each with three fruit names
data = [
    ["Apple", "Banana", "Orange"],
    ["Mango", "Pineapple", "Grape"],
    ["Kiwi", "Strawberry", "Blueberry"]
]

# Convert data to DataStore format: list of dictionaries
# this is Grok's idea and it doesn't work
# grid_view.DataStore = [
#     {
#         "Fruit 1": row[0],
#         "Fruit 2": row[1],
#         "Fruit 3": row[2]
#     } for row in data
# ]

# this is my idea, and it also doesn't work
grid_view.DataStore = data

print(grid_view.DataStore)

# Create layout and add GridView
layout = Eto.Forms.DynamicLayout()
layout.Padding = Eto.Drawing.Padding(10)
layout.Add(grid_view)



# Set the form's content
form.Content = layout

# Show the form
form.ShowModal()

If you’d like to use Python 3 or know more, there are some examples here that may help :slight_smile:

I’m having some issues with the examples provided at this link. When I run any of the examples, Rhino crashes with this report:

[ERROR] FATAL UNHANDLED EXCEPTION: Python.Runtime.PythonException: unhashable type: 'list'
   at Python.Runtime.PythonException.ThrowLastAsClrException()
   at Python.Runtime.PyObject.GetHashCode()
   at System.Collections.Hashtable.ContainsKey(Object key)
   at System.Windows.Automation.Peers.ItemPeersStorage`1.set_Item(Object item, T value)
   at System.Windows.Automation.Peers.ItemsControlAutomationPeer.GetChildrenCore()
   at System.Windows.Automation.Peers.DataGridAutomationPeer.GetChildrenCore()
   at System.Windows.Automation.Peers.AutomationPeer.EnsureChildren()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateChildrenInternal(Int32 invalidateLimit)
   at System.Windows.Automation.Peers.ItemsControlAutomationPeer.UpdateChildren()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.ContextLayoutManager.fireAutomationEvents()
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.Interop.HwndSource.Process_WM_SIZE(UIElement rootUIElement, IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Interop.HwndSource.LayoutFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
[END ERROR]
System Info

Rhino 8 SR24 2025-10-8 (Rhino 8, 8.24.25281.15001, Git hash:master @ ba28668a8431990c700173e46ef2dbcb873cf092)
License type: Commercial, build 2025-10-08
License details: Cloud Zoo

Windows 11 (10.0.26200 SR0.0) or greater (Physical RAM: 192GB)
.NET 8.0.14

Computer platform: DESKTOP

Standard graphics configuration.
Primary display and OpenGL: NVIDIA RTX A4000 (NVidia) Memory: 16GB, Driver date: 9-22-2025 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 581.42
> Accelerated graphics device with 4 adapter port(s)
- Windows Main Display attached to adapter port #0
- Secondary monitor attached to adapter port #1

Secondary graphics devices.
Microsoft Basic Display Adapter (Microsoft) Memory: 0MB, Driver date: 6-21-2006 (M-D-Y).
> External USB display device with 1 adapter port(s)
- Secondary monitor attached to adapter port #0

OpenGL Settings
Safe mode: Off
Use accelerated hardware modes: On
GPU Tessellation is: On
Redraw scene when viewports are exposed: On
Graphics level being used: OpenGL 4.6 (primary GPU’s maximum)

Anti-alias mode: 8x
Mip Map Filtering: Linear
Anisotropic Filtering Mode: High

Vendor Name: NVIDIA Corporation
Render version: 4.6
Shading Language: 4.60 NVIDIA
Driver Date: 9-22-2025
Driver Version: 32.0.15.8142
Maximum Texture size: 32768 x 32768
Z-Buffer depth: 24 bits
Maximum Viewport size: 32768 x 32768
Total Video Memory: 16376 MB

Rhino plugins that do not ship with Rhino
C:\Users\Domenic Gallo\AppData\Roaming\McNeel\Rhinoceros\8.0\Plug-ins\Speckle.Connectors.Rhino8 (2153799A-0CEC-40DE-BC3A-01E5055222FF)\Speckle.Connectors.Rhino8.rhp “Speckle” 3.10.0.0

Rhino plugins that ship with Rhino
C:\Program Files\Rhino 8\Plug-ins\Commands.rhp “Commands” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\rdk.rhp “Renderer Development Kit”
C:\Program Files\Rhino 8\Plug-ins\RhinoRenderCycles.rhp “Rhino Render” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\rdk_etoui.rhp “RDK_EtoUI” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\NamedSnapshots.rhp “Snapshots”
C:\Program Files\Rhino 8\Plug-ins\MeshCommands.rhp “MeshCommands” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\IronPython\RhinoDLR_Python.rhp “IronPython” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\RhinoCycles.rhp “RhinoCycles” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\Grasshopper\GrasshopperPlugin.rhp “Grasshopper” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\RhinoCode\RhinoCodePlugin.rhp “RhinoCodePlugin” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\Toolbars\Toolbars.rhp “Toolbars” 8.24.25281.15001
C:\Program Files\Rhino 8\Plug-ins\Displacement.rhp “Displacement”
C:\Program Files\Rhino 8\Plug-ins\SectionTools.rhp “SectionTools”

Thanks for the report. I tested these on Windows so this is definitely a regression. I can reproduce the borking, and I’ve logged a bug report here
https://mcneel.myjetbrains.com/youtrack/issue/RH-90150/unhashable-type-list