WPF 4 DataGrid Row Drag and Drop

Abstract: The WPF DataGrid control has lots of features for data representations and manipulations (like row column drag drop). One of the nicest features of the DataGrid, is that we can change the column position using Drag-Drop. In this article, we will see how to implement Drag and Drop in a DataGrid Row.

I recently had a discussion with a colleague about the capabilities of WPF for application development. We had discussions on the various new features in WPF including the capabilities of the WPF DataGrid control. The WPF DataGrid control has lots of features for data representations and manipulation. One of the nicest features of the DataGrid, is that we can change the column position using Drag-Drop. When my colleague asked me if the Drag-Drop effect is possible for the DataGridRow too, I was clueless. But this question gave me enough motivation to try my hands on implementing a Drag drop with the DataGridRow. This article demonstrates how to do so.

Step 1: Open VS2010 and create a WPF windows application. Name it as ‘WPF40_DataGrid_Row_Drag_Drop’.

Step 2: To this project, add a new class file and name it as ‘DataAccess.cs’. Write the following code in it:

The above class, defines classes for Employee Entity and the EmployeeCollection, to store Employee records.

Step 3: Open MainWindow.Xaml and define an instance for the ‘EmployeeCollection’ class in Windows.Resource. Also define the DataGrid columns and set the AllowDrop property of the DataGrid to ‘true’. This will enable Drag-Drop operations on the DataGrid control.

Step 4: Now we need to write some code which will provide the DataGridRow Drag-Drop functionality. To do so, open MainWindow.xaml.cs and define a delegate. This delegate will return the position of the Mouse Button event and Drag-Drop event. This delegate accepts an ‘IInputElement’ interface object, which is used to establish the common event and event related properties and methods for WPF element input processing. Here the input is sent using a Mouse button. The delegate is declared at the namespace level as shown below:

After declaring the delegate, we now need to check if the Mouse is placed on the DataGridRow for Drag-Drop operation. To do this, a method is written which returns Boolean and accepts two parameters - the first parameter is the ‘Visual’ object which provides rendering to the WPF application and the second parameter is the ‘GetDragDropPosition’ delegate. This method provides logic for capturing the Rectangle ‘Rect’ information, within which the rendering of the Drag-Drop operations is managed using ‘Point’ object, which is provided by the Visual object. So if the ‘Rect’ contains the specified point for Drag-Drop, the method returns true. Here’s the code for this method:

Now we need to get the DataGridRow for Drag-Drop. The method is as shown below:

Now it’s time for us to define the logic for getting the Drag-Drop index for the DataGridRow. To do so, we need to iterate through the ‘Items’ property of the DataGrid, then retrieve the DataGridRow for the specific index and check whether it is on the Mouse Target with its Rect position, which we defined earlier using ‘IsTheMouseOnTarget’ method

Now declare the class level variable for keeping track of the DaraGridRow object index:

int prevRowIndex = -1;

After following the above steps, we now need to implement ’PreviewMouseLeftButtonDown’ event of DataGrid, which will get the Employee object on the selected index and will provide the Drag-Drop effect. The code for the same is as shown below:

Step 5: Let us now implement the drop event of the DataGrid. This will track the Drop index, so once the drop operation is completed, the Row will be removed from the previous index and will be inserted at a new index.

Finally just hook these events in the constructor, as shown below:

Step 6: That’s it! Run the application, drag a Row from the DataGrid and drop it at a new index. Note: WPF DataGrid always shows the last row which is empty. This row is used for Insert operation in the DataGrid, so the Drag-Drop is not applicable there and we have checked this is in the Drop event. Output, when the screen loads:

After Drag-Drop: Employee No. 4 is dropped to position 2.

and here’s the error message if you try to drop a row in the last row:

Conclusion: In this article, we saw how to implement Drag-Drop effect for the WPF DataGridRow. The entire source code of this article can be downloaded over here

Was this article worth reading? Share it with fellow developers too. Thanks!

Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet

Feedback - Leave us some adulation, criticism and everything in between!

I think if you try to drag a row outside the bounds of the datagrid (for scrolling), it will throw an exception in the IsMouseOnTargetRow method, where the VisualTreeHelper.GetDescendantBounds call fails. This may be what Jeffrey was referring to.

Comment posted by
Sven Turowski
on Tuesday, July 9, 2013 1:32 AM

The article is extremly helpful!
Thanks a lot!!

Sven

Comment posted by
cheshire cat
on Wednesday, October 23, 2013 6:21 PM

doesn't work with comboboxes: it doesn't select the items...

Comment posted by
Faiyaz Khan
on Monday, June 30, 2014 10:47 PM

Good article, I used it in my recent development. Additionally if want grid to scroll up and down please use below code.