When I was working in OneSync project, our team was once asked if there was a way to implement drag-and-drop reordering in the ListView control. We answered no because we could not find any way to implement that functionality. In the end, we used two buttons: Up and Down for reordering the rows in listView.
Last week, I was again asked by my friend to implement similar stuff in WPF. I tried to google and I found the solution, finally: http://www.codeproject.com/KB/WPF/ListViewDragDropManager.aspx. There are three major classes I use in the new project:
- ListViewDragDrop.cs: Manages the drag-and-drop reordering in ListView.
- DragAdorner.cs: Draws a translucent listViewItem on top of the ListView and makes it follow the cursor during the drag-and-drop operation.
- MouseUtilities.cs: There is a method which returns the position of the cursor.
I find the MouseUtilities class to be quite interesting. The author of the method is Dan Crevier from Microsoft. According to the documentation, the purpose of having the class is because “the WPF mechanisms for retrieving the cursor coordinates are unreliable”.
It uses unmanaged code to solve the problem. After coding in C# for several years, I am getting used to reading the managed code, but not unmanaged code in C#. However, for those who are good at C and C++, they can try reading the code in MouseUtilities.cs.
Drag-and-Drop or Up-and-Down Buttons?
In fact, I like the Up and Down buttons very much because they allow the last item in the list to become the first item with just one click on the Down button. If we use the drag-and-drop feature, then we have to drag the last item all the way up to the top of the list. It will be quite troublesome when the list is very long.