diff --git a/DragDropDataGridToTreeGrid.png b/DragDropDataGridToTreeGrid.png new file mode 100644 index 0000000..88e07d1 Binary files /dev/null and b/DragDropDataGridToTreeGrid.png differ diff --git a/README.md b/README.md index c3fc145..b07781a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,154 @@ -# How to drag and drop rows between datagrid and listview in wpf? -This example illustrates how to drag and drop rows between datagrid and listview in wpf +# How to Drag and Drop Rows Between WPF DataGrid and WPF TreeGrid? + +This example illustrates how to drag and drop rows between [WPF DataGrid](https://www.syncfusion.com/wpf-controls/datagrid) (SfDataGrid) and [WPF TreeGrid](https://www.syncfusion.com/wpf-controls/treegrid) (SfTreeGrid). + +To perform the dragging operation between DataGrid and TreeGrid by using the [GridRowDragDropController.Drop](https://help.syncfusion.com/cr/wpf/Syncfusion.UI.Xaml.Grid.GridRowDragDropController.html#Syncfusion_UI_Xaml_Grid_GridRowDragDropController_Drop) and [TreeGridRowDragDropController.Drop](https://help.syncfusion.com/cr/wpf/Syncfusion.UI.Xaml.TreeGrid.TreeGridRowDragDropController.html#Syncfusion_UI_Xaml_TreeGrid_TreeGridRowDragDropController_Drop) events. + +``` c# +this.sfDataGrid.RowDragDropController.Drop += sfDataGrid_Drop; +this.sfTreeGrid.RowDragDropController.Drop += sfTreeGrid_Drop; + +/// +/// Customized TreeGrid Drop event. +/// +/// +/// +private void sfTreeGrid_Drop(object sender, TreeGridRowDropEventArgs e) +{ + if (e.IsFromOutSideSource) + { + var draggingRecord = e.Data.GetData("Records") as ObservableCollection; + var record = draggingRecord[0] as EmployeeInfo; + var dropPosition = e.DropPosition.ToString(); + var newItem = new EmployeeInfo(); + var rowIndex =AssociatedObject.sfTreeGrid.ResolveToRowIndex(e.TargetNode.Item); + if (dropPosition != "None" && rowIndex != -1) + { + if (AssociatedObject.sfTreeGrid.View is TreeGridSelfRelationalView) + { + var treeNode = e.TargetNode; + if (treeNode == null) + return; + var data = treeNode.Item; + AssociatedObject.sfTreeGrid.SelectionController.SuspendUpdates(); + var dropIndex = -1; + TreeNode parentNode = null; + if (dropPosition == "DropBelow" || dropPosition == "DropAbove") + { + parentNode = treeNode.ParentNode; + if (parentNode == null) + { + var treeNodeItem = treeNode.Item as EmployeeInfo; + newItem = new EmployeeInfo() { FirstName = record.FirstName, LastName = record.LastName, ID = record.ID, Salary = record.Salary, Title = record.Title, ReportsTo = treeNodeItem.ReportsTo }; + } + else + { + var parentNodeItems = parentNode.Item as EmployeeInfo; + newItem = new EmployeeInfo() { FirstName = record.FirstName, LastName = record.LastName, ID = record.ID, Salary = record.Salary, Title = record.Title, ReportsTo = parentNodeItems.ID }; + } + } + else if (dropPosition == "DropAsChild") + { + if (!treeNode.IsExpanded) + AssociatedObject.sfTreeGrid.ExpandNode(treeNode); + parentNode = treeNode; + var parentNodeItems = parentNode.Item as EmployeeInfo; + newItem = new EmployeeInfo() { FirstName = record.FirstName, LastName = record.LastName, ID = record.ID, Salary = record.Salary, Title = record.Title, ReportsTo = parentNodeItems.ID }; + } + IList sourceCollection = null; + if (dropPosition == "DropBelow" || dropPosition == "DropAbove") + { + if (treeNode.ParentNode != null) + { + var collection = AssociatedObject.sfTreeGrid.View.GetPropertyAccessProvider().GetValue(treeNode.ParentNode.Item, AssociatedObject.sfTreeGrid.ChildPropertyName) as IEnumerable; + sourceCollection = GetSourceListCollection(collection); + } + else + { + sourceCollection = GetSourceListCollection(AssociatedObject.sfTreeGrid.View.SourceCollection); + } + dropIndex = sourceCollection.IndexOf(data); + if (dropPosition == "DropBelow") + { + dropIndex += 1; + } + } + else if (dropPosition == "DropAsChild") + { + var collection = AssociatedObject.sfTreeGrid.View.GetPropertyAccessProvider().GetValue(data, AssociatedObject.sfTreeGrid.ChildPropertyName) as IEnumerable; + sourceCollection = GetSourceListCollection(collection); + if (sourceCollection == null) + { + var list = data.GetType().GetProperty(AssociatedObject.sfTreeGrid.ChildPropertyName).PropertyType.CreateNew() as IList; + if (list != null) + { + AssociatedObject.sfTreeGrid.View.GetPropertyAccessProvider().SetValue(treeNode.Item, AssociatedObject.sfTreeGrid.ChildPropertyName, list); + sourceCollection = list; + } + } + dropIndex = sourceCollection.Count; + } + sourceCollection.Insert(dropIndex, newItem); + AssociatedObject.sfTreeGrid.SelectionController.ResumeUpdates(); + (AssociatedObject.sfTreeGrid.SelectionController as TreeGridRowSelectionController).RefreshSelection(); + e.Handled = true; + } + } + AssociatedObject.sfDataGrid.View.Remove(record); + } +} + +/// +/// Gets the source collection of TreeGrid +/// +/// +/// +private IList GetSourceListCollection(IEnumerable collection) +{ + IList list = null; + if (collection == null) + collection = AssociatedObject.sfTreeGrid.View.SourceCollection; + if ((collection as IList) != null) + { + list = collection as IList; + } + return list; +} + +/// +/// Customize the Drop event.restrict the certain record and Drop position from drop. +/// +/// +/// +private void sfDataGrid_Drop(object sender, GridRowDropEventArgs e) +{ + if (e.IsFromOutSideSource) + { + var draggingRecord = e.Data.GetData("Nodes") as ObservableCollection; + var record = draggingRecord[0].Item as EmployeeInfo; + int dropIndex = (int)e.TargetRecord; + var dropPosition = e.DropPosition.ToString(); + if (record.Title == "Manager") + { + e.Handled = true; + return; + } + IList collection = null; + collection = AssociatedObject.sfDataGrid.View.SourceCollection as IList; + if (dropPosition == "DropAbove") + { + dropIndex--; + collection.Insert(dropIndex, record); + } + else + { + dropIndex++; + collection.Insert(dropIndex, record); + } + AssociatedObject.sfTreeGrid.View.Remove(record); + e.Handled = true; + } +} +``` + +![Drag and drop between DataGrid and TreeGrid](DragDropDataGridToTreeGrid.png) \ No newline at end of file