This example illustrates how to drag and drop rows between WPF TreeGrid / UWP TreeGrid (SfTreeGrid) and listview.
You can drag the item from ListView and drop into TreeGrid by overriding the GetDropPosition, ProcessOnDragOver, and ProcessOnDrop methods in the TreeGridRowDragDropController class.
In ListView, use the DragItemsStarting event and add dragged item.
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<PersonInfo>).Remove(item as PersonInfo);
}
}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.