如何基于DevExpress实现数据库关联TreeView/TreeList及同步、拖拽功能?
1. Building a Database-Bound TreeList
You’re already on the right track with setting TreeList.ViewStyle to TreeView for that classic tree appearance. Here’s how to fully tie it to your database, via designer or code:
Designer Approach
- Drop a
TreeListonto your form, then use its smart tag to connect to your data source (e.g., aSqlDataSourceorBindingSourcelinked to your database table). - Open the TreeList Designer, navigate to the Data tab:
- Set
KeyFieldNameto your unique node ID column (likeNodeID). - Set
ParentFieldNameto the column that references the parent node’s ID (likeParentNodeID).
- Set
- Enable
TreeList.OptionsBehavior.Editableif you want users to modify node values directly.
Programmatic Approach
// Assume you have a populated DataTable with NodeID, ParentNodeID, NodeText columns treeList1.KeyFieldName = "NodeID"; treeList1.ParentFieldName = "ParentNodeID"; treeList1.DataSource = yourDatabaseDataTable; treeList1.ViewStyle = DevExpress.XtraTreeList.ViewStyle.TreeView; treeList1.OptionsBehavior.Editable = true;
2. Two-Way Sync Between TreeList and Database
To keep your database in sync with edits and drag operations, you’ll need to handle TreeList events and implement data update logic:
a. Auto-Update on Cell Edits
Catch the CellValueChanged event to push edits to the database immediately:
private void treeList1_CellValueChanged(object sender, DevExpress.XtraTreeList.CellValueChangedEventArgs e) { var treeList = sender as TreeList; var editedNode = e.Node; // Extract updated values int nodeId = (int)editedNode.GetValue("NodeID"); string newNodeText = e.Value.ToString(); // Use parameterized queries to avoid SQL injection using (var conn = new SqlConnection(yourConnectionString)) { string updateQuery = "UPDATE YourTable SET NodeText = @NewText WHERE NodeID = @NodeID"; var cmd = new SqlCommand(updateQuery, conn); cmd.Parameters.AddWithValue("@NewText", newNodeText); cmd.Parameters.AddWithValue("@NodeID", nodeId); conn.Open(); cmd.ExecuteNonQuery(); } }
b. Sync Parent Changes After Drag-and-Drop
When a node is moved to a new parent, update its ParentNodeID in the database. First enable drag-and-drop (covered in section 3), then handle the DragDrop event:
private void treeList1_DragDrop(object sender, DragEventArgs e) { var treeList = sender as TreeList; var targetParentNode = treeList.CalcHitInfo(treeList.PointToClient(new Point(e.X, e.Y))).Node; var draggedNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode; if (targetParentNode != null && draggedNode != null) { // Update the TreeList's parent reference first int newParentId = (int)targetParentNode.GetValue("NodeID"); draggedNode.SetValue("ParentNodeID", newParentId); // Push change to database int draggedNodeId = (int)draggedNode.GetValue("NodeID"); using (var conn = new SqlConnection(yourConnectionString)) { string updateQuery = "UPDATE YourTable SET ParentNodeID = @NewParentID WHERE NodeID = @DraggedNodeID"; var cmd = new SqlCommand(updateQuery, conn); cmd.Parameters.AddWithValue("@NewParentID", newParentId); cmd.Parameters.AddWithValue("@DraggedNodeID", draggedNodeId); conn.Open(); cmd.ExecuteNonQuery(); } // Refresh TreeList to show updated hierarchy treeList.Refresh(); } }
3. Implementing Node Drag-and-Drop
Enable drag-and-drop functionality with these steps:
Designer Approach
- Open the TreeList Designer, go to the Behavior tab.
- Set
OptionsDragAndDrop.DragNodesModetoSingleorMultiple(based on your needs). - Check
OptionsDragAndDrop.AllowDragandOptionsDragAndDrop.AllowDropto enable the feature.
Programmatic Approach
treeList1.OptionsDragAndDrop.DragNodesMode = DevExpress.XtraTreeList.DragNodesMode.Single; treeList1.OptionsDragAndDrop.AllowDrag = true; treeList1.OptionsDragAndDrop.AllowDrop = true;
Optional: Restrict Invalid Drops
Add a DragOver handler to prevent invalid operations (like dropping a node into its own descendant):
private void treeList1_DragOver(object sender, DragEventArgs e) { var treeList = sender as TreeList; var targetNode = treeList.CalcHitInfo(treeList.PointToClient(new Point(e.X, e.Y))).Node; var draggedNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode; // Block dropping a node into its own child hierarchy if (targetNode != null && draggedNode != null && targetNode.HasAsParent(draggedNode)) { e.Effect = DragDropEffects.None; } else { e.Effect = DragDropEffects.Move; } }
Bonus: Simplify Sync with ORMs
If you’re using an ORM like Entity Framework, bind the TreeList to an ObservableCollection of your entity objects. When values or parent IDs change, just call dbContext.SaveChanges()—this eliminates writing raw SQL and streamlines sync logic.
内容的提问来源于stack exchange,提问作者climivin

