Wednesday, July 1, 2009

DragDropManager for WPF TreeViews and ListViews

Update: Please note that the download for this project has been moved here.

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.
  1. Move a category within the TreeView
  2. Move an item within the ListView
  3. Link an item with another category
The demo is available for download here. The drag-and-drop setup code in the demo looks like this:

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 );
}

Obfuscation for .NET

Update (1 November 2012):
I recently tried upgrading to the latest Smart Assembly version (now owned by Red Gate) while in the process of upgrading my project to .NET Framework 4.5. The latest Smart Assembly version seemed to work okay at first, but then I discovered a bug that caused it to crash. I sent a bug report to Red Gate, along with a repro, then waited and bugged them until I finally received a reply that said: "I'm hopeful that a release may be available with a couple of weeks, however there's no full time development team currently working on Smartassembly; the majority are deployed on other tools." This was especially infuriating since I had purchased "1 year Support & Upgrades". What kind of support is this? None at all, I think. My conclusion is that development on Smart Assembly is stagnant. Therefore, it's best to consider the product dead.

Original Post:
I recently had to fulfill my need for an obfuscation utility for .NET. More specifically, I needed a solution that works with WPF. I learned that WPF poses a particular challenge concerning obfuscation, since the BAML format has not been made public by Microsoft.

My first attempt was using Dotfuscator Community Edition which comes bundled with Visual Studio. After spending a significant amount of time picking certain properties and methods to exclude, I still couldn't get the obfuscated version of my app to run. So I finally gave up and instead turned to Google to help me find an alternative tool.

The only tool I found, with specific mention of WPF support, was {smartassembly}. As long as I exclude those types and (attached) properties used in XAML, this tool works like a charm.

{smartassembly} projects are stored in an XML format, so you can edit them using either your favorite text editor or {smartassembly}'s designated user-interface. The UI follows a rather interesting concept. It's a gigantic vertically scrollable area, consisting of a collapsible pane for each settings group. It reminds me a lot of a word-processor. This may seem strange at first, but after a couple hours of usage, you'll likely see the design concept's merit points.

{smartassembly} has security and optimization features in addition to simple obfuscation. One of particular interest is error reporting. When your program crashes, error reports can be collected by a server and made available for your viewing. That feature, however, is only available in the Professional and Enterprise editions. The Standard edition will run you 500 USD, and the other editions move up from there. For more information, see the {smartassembly} website.