
Introduction
A personal project to improve the user interface to sort Ordered Tests in Visual Studio required me to have a TreeListView.
I started by searching the Internet and find a free control that I could use. I figured out some amazing controls, but the
best for me was TreeListView by Thomas Caudal. That control worked fine,
supports columns, edit, checkboxes etc. One of my requirements is support drag
and drop functionality between different TreeListViews to move items between lists and order those,
unfortunately (maybe fortunately otherwise I did not write this article) the TreeListView did not support that functionality. One more
time I searched by a free control that could satisfy my expectative but no lucky. So I decided implement that functionality by myself using as base
Thomas’s TreeListView. To achieve that I searched again and that pointed me towards
Drag and Drop List View
by Matt Hawley. His control allows to reorder items in a ListView and supports moving to other ListViews indicating the position where is going to be
the item in moving.
I decided to merge those two good jobs.
Let's Merge
I got both source codes, and I started renaming TreeListView to
TreeListViewEx (use your own name is stimulant factor). After my first look at to the
implementation of TreeListView.cs. I fall into account it had more than 2 thousand lines of code. It is a lot of code and adding the support for drag and
drop is going to be hard but no way, I got help from my friends the partial class, so for each class related with the TreeListView I am adding a partial
class with the suffix .draganddrop.cs.
The Partial Class TreeListViewItem.draganddrop.cs
The drag and drop implementation works making a clone of each item to be moved. The clone is added to its new position
and then the original item is removed from its source. The original implementation supported clone the
ListView, my implementation has to support
clone the TreeListViewItem and all its children.
public partial class TreeListViewItem
{
public override object Clone()
{
var clone = new TreeListViewItem(Text, ImageIndex);
for (int index = 1; index < SubItems.Count; index++)
{
object subItem = SubItems[index];
clone.SubItems.Add((ListViewSubItem) subItem);
}
foreach (ICloneable item in Items)
{
clone.Items.Add((TreeListViewItem) ((TreeListViewItem) item).Clone());
}
clone.Group = Group;
clone.IndentCount = IndentCount;
clone.IsExpanded = IsExpanded;
clone.ToolTipText = ToolTipText;
clone.Checked = Checked;
clone.Tag = Tag;
return clone;
}
}
The Partial Class
TreeListView.draganddrop.cs
The
implementation of this class was practically a copy paste of a "drag and drop” implementation renaming all
ListView and ListViewItem by
TreeListView and TreeListViewItem. So far the project compiles and runs but it
has a lot of issues, due that not all the implementation of TreeListView works with
the drag and drop. So I had to fix
all those weird behaviors and crashes with the debugger help (maybe it was the
hardest part of this merge).
Fine tuning the drawing for
Drag and Drop
The initial
implementation for drag and drop drew a line indicating where the item is going
to be moved this line cross the whole ListView. In the children of
TreeListView, that line looked weird due that a child has an indentation. Fixing the problem by resizing based on the indentation we have the next:

Conclusions
Is
interesting how open source can grow up. Without those previous implementations
I would not achieved my target, or it would take a lot of time. Thanks to
Thomas and Matt for theirs initiative. Today
I have a most complete implementation and nobody knows when somebody is going
to take this code and improve it again.
Known Problems
- No way to add items to an empty item. Who want add this functionality?
History
- September, 2012: First implementation working.