WPF DataGrid Drag & Drop and target Row Indicator effect

  1. Enable Drag & Drop for grid: Below are the events which I used to enable drag & drop, other than these there are other DataGrid events like DragEnter, DragOver and DragLeave which you can make use of for your need.
    i. Enable AllowDrop=”True” and SelectionMode=”Extended” for the grid.
    ii. Add LoadingRow event for dragging rows and indicator line effects. Below mentioned effects code is been handled from this event.
    iii. Add SelectionChanged event to mark selected rows. This event will set Model.IsSelected to true through which we identify this row(s) are selected.
    iv. Add Drop event and the code related to dropping rows goes here, this is where collection source gets modified.
  2. Show the selected rows while dragging: This you can achieve by adding a popup and this is all you need to do:
    i. Design a container control (in my case I added a grid with no header) to show data (selected rows).
    ii. Create a popup and place the above container control within the popup.
    iii. From the code behind On Row_DragOver event bind the container control and display the popup on current mouse position and otherwise hide the popup.
private void PersonGrid_LoadingRow(object sender, DataGridRowEventArgs e){      e.Row.DragOver += Row_DragOver;}private void Row_DragOver(object sender, DragEventArgs e){     if (!popup1.IsOpen)     {           popup1.IsOpen = true;
//bind your container control with selected rows of data.
} Size popupSize = new Size(popup1.ActualWidth, popup1.ActualHeight); popup1.PlacementRectangle = new Rect(e.GetPosition(this), popupSize);}
public enum DragRowEffect{     None,     Before,     After}
private DragRowEffect rowEffect;public DragRowEffect RowEffect{       get => rowEffect;       set => SetProperty(ref rowEffect, value); //Prism.Mvvm.BindableBase}
private void Row_DragOver(object sender, DragEventArgs e){      if (!popup1.IsOpen)
{
popup1.IsOpen = true; //bind your container control with selected rows of data.
}
Size popupSize = new Size(popup1.ActualWidth, popup1.ActualHeight);
popup1.PlacementRectangle = new Rect(e.GetPosition(this), popupSize);
var targetRowIndex = dataContext.PersonCollection.IndexOf((e.OriginalSource as FrameworkElement).DataContext as Person);
if (targetRowIndex < 0)
return;
var selectedItemsIndexes = selectedItems.Select(x => dataContext.PersonCollection.IndexOf(x)).OrderBy(x => x).ToList();
var minIndex = selectedItemsIndexes.Min();
if (targetRowIndex == 0)
dataContext.PersonCollection[targetRowIndex].RowEffect = DragRowEffect.Before;
else if (minIndex > targetRowIndex)
dataContext.PersonCollection[targetRowIndex].RowEffect = DragRowEffect.Before;
else
dataContext.PersonCollection[targetRowIndex].RowEffect = DragRowEffect.After;
}
<DataGrid.RowStyle><Style TargetType="{x:Type DataGridRow}"><Setter Property="SnapsToDevicePixels" Value="true"/><Setter Property="Background" Value="Transparent"/><Setter Property="VerticalAlignment" Value="Center"/><Setter Property="MinHeight" Value="40"/><Style.Triggers><DataTrigger Binding="{Binding RowEffect}" Value="1"><Setter Property="BorderBrush" Value="Blue" /><Setter Property="BorderThickness" Value="0,2,0,0" /></DataTrigger><DataTrigger Binding="{Binding RowEffect}" Value="2"><Setter Property="BorderBrush" Value="Blue" /><Setter Property="BorderThickness" Value="0,0,0,2" /></DataTrigger><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="LightGray" /></Trigger><Trigger Property="IsSelected" Value="True"><Setter Property="Background" Value="LightGray" /></Trigger><Trigger Property="IsNewItem" Value="True"><Setter Property="Margin" Value="{Binding NewItemMargin, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/></Trigger></Style.Triggers></Style></DataGrid.RowStyle>

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Binod Mahto

Binod Mahto

141 Followers

Solution Architect & Full Stack Developer. Passionate about Software designing & development and Learning Technologies and Love to share what I learn.