How to make row drag and drop between UWP DataGrid (SfDataGrid) and other UWP control?
UWP DataGrid (SfDataGrid) offers a built-in support for row drag and drop functionality by enabling SfDataGrid.AllowDraggingRows and AllowDrop property. This topic demonstrates row drag-and-drop operations between DataGrid with other controls.
<syncfusion:SfDataGrid x:Name="dataGrid"
AllowDraggingRows="True"
AllowDrop="True"
LiveDataUpdateMode="AllowDataShaping"
ItemsSource="{Binding UserDetails}" >
You can able to perform the row drag and drop between DataGrid with other control like ListView and others also. For this operation, you should override a RowDragDropController.ProcessOnDragOver and RowDragDropController.ProcessOnDrop to handle the drag and drop operations.
this.sfDataGrid.RowDragDropController = new GridRowDragDropControllerExt();
public class GridRowDragDropControllerExt : GridRowDragDropController
{
ObservableCollection<object> draggingRecords = new ObservableCollection<object>();
/// <summary>
/// Occurs when the input system reports an underlying dragover event with this element as the potential drop target.
/// </summary>
/// <param name="args">An <see cref="T:Windows.UI.Xaml.DragEventArgs">DragEventArgs</see> that contains the event data.</param>
/// <param name="rowColumnIndex">Specifies the row column index based on the mouse point.</param>
protected override void ProcessOnDragOver(DragEventArgs args, RowColumnIndex rowColumnIndex)
{
if (args.DataView.Properties.ContainsKey("DraggedItem"))
draggingRecords = args.DataView.Properties["DraggedItem"] as ObservableCollection<object>;
else
draggingRecords = args.DataView.Properties["Records"] as ObservableCollection<object>;
if (draggingRecords == null)
return;
//To get the dropping position of the record
var dropPosition = GetDropPosition(args, rowColumnIndex, draggingRecords);
//To Show the draggable popup with the DropAbove/DropBelow?None message
if (dropPosition == DropPosition.None)
{
CloseDragIndicators();
args.AcceptedOperation = DataPackageOperation.None;
args.DragUIOverride.Caption = "Can't drop here";
return;
}
else if (dropPosition == DropPosition.DropAbove)
{
if (draggingRecords != null && draggingRecords.Count > 1)
args.DragUIOverride.Caption = "Drop these " + draggingRecords.Count + " rows above";
else
{
args.AcceptedOperation = DataPackageOperation.Copy;
args.DragUIOverride.IsCaptionVisible = true;
args.DragUIOverride.IsContentVisible = true;
args.DragUIOverride.IsGlyphVisible = true;
args.DragUIOverride.Caption = "Drop above";
}
}
else
{
if (draggingRecords != null && draggingRecords.Count > 1)
args.DragUIOverride.Caption = "Drop these " + draggingRecords.Count + " rows below";
else
args.DragUIOverride.Caption = "Drop below";
}
args.AcceptedOperation = DataPackageOperation.Move;
//To Show the up and down indicators while dragging the row
ShowDragIndicators(dropPosition, rowColumnIndex, args);
args.Handled = true;
}
ListView listview;
/// <summary>
/// Occurs when the input system reports an underlying drop event with this element as the drop target.
/// </summary>
/// <param name="args">An <see cref="T:Windows.UI.Xaml.DragEventArgs">DragEventArgs</see> that contains the event data.</param>
/// <param name="rowColumnIndex">Specifies the row column index based on the mouse point.</param>
protected override void ProcessOnDrop(DragEventArgs args, RowColumnIndex rowColumnIndex)
{
listview = null;
if (args.DataView.Properties.ContainsKey("ListView"))
listview=args.DataView.Properties["ListView"] as ListView;
if (!DataGrid.SelectionController.CurrentCellManager.CheckValidationAndEndEdit())
return;
//To get the dropping position of the record
var dropPosition = GetDropPosition(args, rowColumnIndex, draggingRecords);
if (dropPosition == DropPosition.None)
return;
// to get the index of dropping record
var droppingRecordIndex = this.DataGrid.ResolveToRecordIndex(rowColumnIndex.RowIndex);
if (droppingRecordIndex < 0)
return;
// to insert the dragged records based on dragged position
foreach (var record in draggingRecords)
{
if (listview != null)
{
(listview.ItemsSource as ObservableCollection<BusinessObjects>).Remove(record as BusinessObjects);
var sourceCollection = this.DataGrid.View.SourceCollection as IList;
if (dropPosition == DropPosition.DropBelow)
sourceCollection.Insert(droppingRecordIndex + 1, record);
else
sourceCollection.Insert(droppingRecordIndex, record);
}
else
{
var draggingIndex = this.DataGrid.ResolveToRowIndex(draggingRecords[0]);
if (draggingIndex < 0)
{
return;
}
// to get the index of dragging row
var recordindex = this.DataGrid.ResolveToRecordIndex(draggingIndex);
var recordEntry = this.DataGrid.View.Records[recordindex];
this.DataGrid.View.Records.Remove(recordEntry);
// to insert the dragged records to particular position
if (draggingIndex < rowColumnIndex.RowIndex && dropPosition == DropPosition.DropAbove)
this.DataGrid.View.Records.Insert(droppingRecordIndex - 1, this.DataGrid.View.Records.CreateRecord(record));
else if (draggingIndex > rowColumnIndex.RowIndex && dropPosition == DropPosition.DropBelow)
this.DataGrid.View.Records.Insert(droppingRecordIndex + 1, this.DataGrid.View.Records.CreateRecord(record));
else
this.DataGrid.View.Records.Insert(droppingRecordIndex, this.DataGrid.View.Records.CreateRecord(record));
}
}
//Closes the Drag arrow indication all the rows
CloseDragIndicators();
}
}
<ListView x:Name="listView" AllowDrop="True" ItemsSource="{Binding OrderDetails1}" DisplayMemberPath="ShipName" >
this.listView.DragItemsStarting += ListView_DragItemsStarting;
ObservableCollection<object> records1 = new ObservableCollection<object>();
/// <summary>
/// to select and the dragging records
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var records = new ObservableCollection<object>();
records.Add(listView.SelectedItem);
e.Data.Properties.Add("DraggedItem", records);
e.Data.Properties.Add("ListView", listView);
e.Data.SetText(StandardDataFormats.Text);
}
this.listView.DragOver += ListView_DragOver;
/// <summary>
/// to move the dragged items form the ListView control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_DragOver(object sender, DragEventArgs e)
{
if (e.DataView.Properties.ContainsKey("Records"))
records1 = e.DataView.Properties["Records"] as ObservableCollection<object>;
}
this.listView.DragEnter += ListView_DragEnter;
/// <summary>
/// to dragged and dropped the selected records in ListView control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_DragEnter(object sender, DragEventArgs e)
{
e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
}
this.listView.Drop += ListView_Drop;
this.listView.Drop += ListView_Drop;
/// <summary>
/// to add the dropped record in the ListView control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_Drop(object sender, DragEventArgs e)
{
foreach (var item in records1)
{
this.datagrid.View.Remove(item as BusinessObjects);
(this.DataContext as ViewModel).GDCSource1.Add(item as BusinessObjects);
}
}
Sample:
Conclusion
I hope you enjoyed learning on how make row drag and drop between DataGrid and other UWP control.
You can refer to our UWP DataGrid feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications. You can also explore our UWP DataGrid example to understand how to create and manipulate data.
For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.
If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!