If you have built a .NET application that needs a tree structure — folders, categories, organizational charts, navigation hierarchies — you know the drill. You find a tree control for the UI, then spend days or weeks writing the data access layer to persist it. Repository classes, EF Core mappings, migration scripts, parent-child queries, sort order management, cascade deletes. The UI control gives you the rendering. Everything else is on you.
HopDev.Tree eliminates that entire layer. It is a .NET tree control that owns its own database tables. Install the NuGet package, register one service, and you have a fully functional tree with automatic persistence to any of five supported databases. The control creates its own tables, manages its own schema, and handles all CRUD operations internally.
Four Lines to a Working Tree
Registration in your MauiProgram.cs or startup class looks like this:
And in XAML:
That is it. The control creates its tables on first run, renders the tree, and persists every add, rename, delete, move, and reorder to the database automatically. No repository classes. No migration scripts. No data access code.
What Makes This Different
Commercial .NET tree controls from DevExpress, Syncfusion, and Telerik are mature, feature-rich products. But they are display components. They render a tree from data you provide and raise events when users interact with it. The entire persistence layer — how that data gets into and out of a database — is your problem.
HopDev.Tree follows what its architecture calls the Embedded Self-Contained System pattern: the control owns everything from pixel rendering down to database schema. It is an in-process microservice that deploys as a NuGet package.
The Feature Set
This is not a minimal control that trades features for simplicity. The v2.1.0 release includes:
Data persistence — five EF Core providers (SQLite, SQL Server, PostgreSQL, Oracle, MySQL), auto-create tables, configurable table prefix, full audit fields on every entity (CreatedAt, CreatedBy, ModifiedAt, ModifiedBy).
Checkbox system — two-state and three-state with cascading (parent checks cascade to children, children roll up to parent), configurable scope (nodes only, items only, or both), and automatic database persistence of checkbox state.
Search and filter — two modes: filter mode hides non-matching nodes, highlight mode shows everything with yellow match highlighting. Match-by-match navigation with previous/next buttons. 300ms debounced input. Works against node names, item names, or both.
Drag and drop — internal reordering within a parent, moving nodes between parents, moving items between nodes, circular reference prevention (cannot drop a node into its own descendants), and external drop support for URLs, text, and files.
Host integration — 18 async callbacks through the ITreeActions interface. Selection events, validation hooks, confirmation dialogs, custom add-item dialogs, lifecycle events for every operation, and a clean anti-corruption layer so the tree never reaches into your application code and your code never reaches into the tree's internals.
Multi-selection — Ctrl+Click to toggle individual nodes, Shift+Click for range selection, Ctrl+A to select all visible nodes. A unified SelectionChanged event fires with Added and Removed collections. Works identically across all four platforms with platform-native modifier key detection.
Localization — 30 sample language providers ship out of the box, including RTL support for Arabic and Hebrew. Runtime language switching without app restart. Every string in the control — context menus, dialog titles, prompts, buttons — is overridable through the ITreeStringProvider interface.
Accessibility — MAUI SemanticProperties, Avalonia and WPF AutomationProperties, Blazor ARIA attributes on all interactive elements. AutomationIds on every control for UI testing. Light, Dark, High Contrast, and System theming across all platforms.
The Data Model
Three tables, cleanly separated from your application data with a configurable prefix:
Hierarchies are root containers — one hierarchy equals one independent tree. Nodes are the folders and branches, organized via a self-referential ParentId. NodeItems are the leaf elements, and their EntityId column is the bridge to your application: it stores the ID of whatever domain entity the item represents (a bookmark, a document, a contact), but the tree never queries your tables. Your app resolves the entity through the ITreeActions callback.
Cross-Platform by Architecture
HopDev.Tree calls its architecture a Hyper-Slice — a vertical slice that goes from UI to database across multiple platforms simultaneously. The shared ViewModel engine (Tree.UI, roughly 1,200 lines) has zero UI framework dependency. Each platform — MAUI, Avalonia, WPF, Blazor — provides a thin rendering skin that translates ViewModel state into native visuals.
This means adding a new platform does not require rewriting the control. It requires writing a rendering skin. The data model, business logic, database persistence, and event system are shared across every platform from a single codebase.
Get Started
HopDev.Tree is MIT-licensed and available now on NuGet and GitHub. The repository includes comprehensive documentation — sixteen reference docs, nine architectural decision records, getting-started guides for each platform and database provider, and sample applications for MAUI, Avalonia, and WPF.
View on GitHub →