My new drag-and-drop manager for WPF, which handles both TreeViews and ListViews, is ready for download. Here's a list of features it includes:
- Supports drag-drop operations among any number of TreeViews and/or ListViews.
- Shows drag adorner while dragging among different TreeViews/ListViews.
- Explicitly supports two types of drop events: ProcessMove for moving an item, and ProcessLink for linking one (see demo).
- User controls where, relative to the item under the drag cursor, the item will be dropped: above, below, or (for TreeViews) within.
- Spiffy animations for grabs, drops, and cancelled operations.
- Auto-expand item if hovering over it during drag operation.
- Auto-scroll TreeView or ListView if near top or bottom edge.
- Works on the standard TreeView and ListView controls. No third-party TreeView or ListView control is required.
- Not dependent upon a particular presentation-model (aka ViewModel) implementation. The pattern isn't even necessary in order to use the DragDropManager.
Demonstration Application
The demo consists of a TreeView that holds categories, and a ListView populated with the selected category's items. These two controls together have a total of three types of drag-drop operations setup on them.- Move a category within the TreeView
- Move an item within the ListView
- Link an item with another category
dragMgr.AddControl<Category>( categoriesTreeView );
dragMgr.AddControl<Item>( itemsListView );
dragMgr.AddHandler<Category>( categoriesTreeView, dragMgr_ProcessMove );
dragMgr.AddHandler<Item>( itemsListView, dragMgr_ProcessMove );
dragMgr.AddHandler<Item, Category>( categoriesTreeView, dragMgr_ProcessLink );
dragMgr.GetLinkEffect += dragMgr_GetLinkEffect;
The first two lines indicate which controls will have their dragging managed. The following three lines add the event handlers whose job is to actually move or link the domain-model objects. The last line adds the custom link animations you will see in the demo.
The body of your ProcessMove and ProcessLink event handlers will depend on how you've architected your presentation-model. The demo app doesn't even use one, so the event handlers simply look like this:
void dragMgr_ProcessMove( object sender, MoveArgs<Category> moveArgs )
{
moveArgs.oldPosition.parent.SubCategories.Remove( moveArgs.itemToMove );
moveArgs.newPosition.parent.SubCategories.Insert(
moveArgs.newPosition.childIndex, moveArgs.itemToMove );
}
void dragMgr_ProcessMove( object sender, FlatMoveArgs<Item> moveArgs )
{
var category = (Category)categoriesTreeView.SelectedItem;
category.Items.RemoveAt( moveArgs.oldIndex );
category.Items.Insert( moveArgs.newIndex, moveArgs.itemToMove );
}
void dragMgr_ProcessLink( object sender, LinkArgs<Item, Category> e )
{
e.TargetLoc.Items.Add( e.ItemToLink );
}