diff --git a/README.md b/README.md index b111736..42327f7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,202 @@ -# How to drag and drop rows in wpf and uwp between listview and treegrid? -This example illustrates how to drag and drop rows in wpf and uwp between listview and treegrid. +# How to Drag and Drop Rows in WPF / UWP between ListView and TreeGrid? + +This example illustrates how to drag and drop rows between [WPF TreeGrid](https://www.syncfusion.com/wpf-controls/treegrid) / [UWP TreeGrid](https://www.syncfusion.com/uwp-ui-controls/treegrid) (SfTreeGrid) and listview. + +You can drag the item from ListView and drop into TreeGrid by overriding the [GetDropPosition](https://help.syncfusion.com/cr/uwp/Syncfusion.UI.Xaml.TreeGrid.TreeGridRowDragDropController.html#Syncfusion_UI_Xaml_TreeGrid_TreeGridRowDragDropController_GetDropPosition_Windows_UI_Xaml_DragEventArgs_Syncfusion_UI_Xaml_ScrollAxis_RowColumnIndex_), [ProcessOnDragOver](https://help.syncfusion.com/cr/uwp/Syncfusion.UI.Xaml.TreeGrid.TreeGridRowDragDropController.html#Syncfusion_UI_Xaml_TreeGrid_TreeGridRowDragDropController_ProcessOnDragOver_Windows_UI_Xaml_DragEventArgs_Syncfusion_UI_Xaml_ScrollAxis_RowColumnIndex_), and [ProcessOnDrop](https://help.syncfusion.com/cr/uwp/Syncfusion.UI.Xaml.TreeGrid.TreeGridRowDragDropController.html#Syncfusion_UI_Xaml_TreeGrid_TreeGridRowDragDropController_ProcessOnDrop_Windows_UI_Xaml_DragEventArgs_Syncfusion_UI_Xaml_ScrollAxis_RowColumnIndex_) methods in the [TreeGridRowDragDropController](https://help.syncfusion.com/cr/uwp/Syncfusion.UI.Xaml.TreeGrid.TreeGridRowDragDropController.html) class. + +In ListView, use the **DragItemsStarting** event and add dragged item. + +``` csharp +listView.CanDragItems = true; +listView.DragItemsStarting += ListView_DragItemsStarting; +listView.DragItemsCompleted += ListView_DragItemsCompleted; + +private void ListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e) +{ + e.Data.Properties.Add("DraggedItem", listView.SelectedItem); + e.Data.SetText(StandardDataFormats.Text); +} + +private void ListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args) +{ + foreach (var item in args.Items) + { + (listView.ItemsSource as ObservableCollection).Remove(item as PersonInfo); + } +} +``` + +``` csharp +public class TreeGridRowDragDropControllerExt : TreeGridRowDragDropController +{ + + public TreeGridRowDragDropControllerExt(SfTreeGrid treeGrid) : base(treeGrid) + { + } + + protected override void ProcessOnDrop(DragEventArgs args, RowColumnIndex rowColumnIndex) + { + this.TreeGrid.AutoScroller.AutoScrolling = AutoScrollOrientation.None; + var dropPosition = GetDropPosition(args, rowColumnIndex); + + if (dropPosition != DropPosition.None && rowColumnIndex.RowIndex != -1) + { + var draggedItem = GetDraggedItem(args); + + if (this.TreeGrid.View is TreeGridNestedView) + { + var treeNode = this.TreeGrid.GetNodeAtRowIndex(rowColumnIndex.RowIndex); + + if (treeNode == null) + return; + var data = treeNode.Item; + TreeGrid.SelectionController.SuspendUpdates(); + var itemIndex = -1; + + TreeNode parentNode = null; + + if (dropPosition == DropPosition.DropBelow || dropPosition == DropPosition.DropAbove) + parentNode = treeNode.ParentNode; + else if (dropPosition == DropPosition.DropAsChild) + { + if (!treeNode.IsExpanded) + TreeGrid.ExpandNode(treeNode); + parentNode = treeNode; + } + IList sourceCollection = null; + + if (dropPosition == DropPosition.DropBelow || dropPosition == DropPosition.DropAbove) + { + + if (treeNode.ParentNode != null) + { + var collection = TreeGrid.View.GetPropertyAccessProvider().GetValue(treeNode.ParentNode.Item, TreeGrid.ChildPropertyName) as IEnumerable; + sourceCollection = GetSourceListCollection(collection); + } + else + { + sourceCollection = GetSourceListCollection(TreeGrid.View.SourceCollection); + } + + itemIndex = sourceCollection.IndexOf(data); + + if (dropPosition == DropPosition.DropBelow) + { + itemIndex += 1; + } + } + else if (dropPosition == DropPosition.DropAsChild) + { + var collection = TreeGrid.View.GetPropertyAccessProvider().GetValue(data, TreeGrid.ChildPropertyName) as IEnumerable; + sourceCollection = GetSourceListCollection(collection); + + if (sourceCollection == null) + { + var list = data.GetType().GetProperty(TreeGrid.ChildPropertyName).PropertyType.CreateNew() as IList; + + if (list != null) + { + TreeGrid.View.GetPropertyAccessProvider().SetValue(treeNode.Item, TreeGrid.ChildPropertyName, list); + sourceCollection = list; + } + } + itemIndex = sourceCollection.Count; + } + sourceCollection.Insert(itemIndex, draggedItem); + TreeGrid.SelectionController.ResumeUpdates(); + (TreeGrid.SelectionController as TreeGridRowSelectionController).RefreshSelection(); + } + } + CloseDragIndicators(); + } + + protected override DropPosition GetDropPosition(DragEventArgs args, RowColumnIndex rowColumnIndex) + { + bool canDrop = true; + var p = args.GetPosition(this.TreeGrid); + var treeNode = this.TreeGrid.GetNodeAtRowIndex(rowColumnIndex.RowIndex); + ScrollAxisRegion columnRegion = ScrollAxisRegion.Body; + var treeGridPanel = TreeGrid.GetTreePanel(); + + if (treeGridPanel.FrozenColumns > 0) + columnRegion = ScrollAxisRegion.Header; + var rowRect = treeGridPanel.RangeToRect(ScrollAxisRegion.Body, columnRegion, rowColumnIndex, true, false); + var node = treeNode; + + if (!canDrop) + return DropPosition.None; + else if (p.Y > rowRect.Y + 15 && p.Y < rowRect.Y + 35) + { + return DropPosition.DropAsChild; + } + else if (p.Y < rowRect.Y + 15) + { + return DropPosition.DropAbove; + } + else if (p.Y > rowRect.Y + 35) + { + return DropPosition.DropBelow; + } + else + return DropPosition.Default; + } + + protected override void ProcessOnDragOver(DragEventArgs args, RowColumnIndex rowColumnIndex) + { + autoExpandNode = null; + var node = this.TreeGrid.GetNodeAtRowIndex(rowColumnIndex.RowIndex); + var draggedItem = GetDraggedItem(args); + var dropPosition = GetDropPosition(args, rowColumnIndex); + + if (draggedItem == null) + return; + + if (dropPosition == DropPosition.None || dropPosition == DropPosition.Default) + { + CloseDragIndicators(); + args.AcceptedOperation = DataPackageOperation.None; + args.DragUIOverride.Caption = "Can't drop here"; + return; + } + else if (dropPosition == DropPosition.DropAbove) + { + args.DragUIOverride.Caption = "Drop above"; + } + else if (dropPosition == DropPosition.DropAsChild) + { + args.DragUIOverride.Caption = "Drop as child"; + } + else + { + args.DragUIOverride.Caption = "Drop below"; + } + args.AcceptedOperation = DataPackageOperation.Move; + ShowDragIndicators(dropPosition, rowColumnIndex); + args.Handled = true; + } + + private object GetDraggedItem(DragEventArgs dragEventArgs) + { + if (dragEventArgs.DataView.Properties.ContainsKey("DraggedItem")) + return dragEventArgs.DataView.Properties["DraggedItem"]; + else + return null; + } + + internal IList GetSourceListCollection(IEnumerable collection = null) + { + IList list = null; + + if (collection == null) + collection = TreeGrid.View.SourceCollection; + + if ((collection as IList) != null) + { + list = collection as IList; + } + return list; + } +} +``` + +After dropping in TreeGrid, the dragged item is added to TreeGrid based on the dropped position.