Wednesday, July 1, 2009

DragDropManager for WPF TreeViews and ListViews

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 DragDropManger.

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


Purchase

If you would like to use the DragDropManager in your own software, please click the "Buy Now" button below. Upon purchase, you will receive the developer assemblies, along with API documentation and demo app source code. Support is provided to ensure you maximally benefit from your purchase. Minor releases, that address any problems that might arise, will also be yours at no additional cost. Together with your feedback, I can make this component the premiere choice for drag-and-drop in WPF. If you have any questions, please contact me at happynomad121@gmail.com.

Price: 119 USD per developer seat
The license conditions stipulate one license per developer seat.
Quantity:

Obfuscation for .NET

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.

Wednesday, April 22, 2009

Non-Intrusive Tree & Graph Types

I just submitted a second article to Code Project. This one is called Non-Intrusive Tree & Graph Types. It's an original subject for me, totally different from my first CP article, so I don't know what to expect. I'm looking forward to see what feedback I'll be getting.

Saturday, January 31, 2009

Drag-and-Drop in a WPF TreeView


Update: Get the latest version of my DragDropManger by clicking here.

When it came to adding drag-and-drop support to my application, the unfortunate dearth of an easy-to-use solution for WPF TreeViews became apparent. The closest thing available was drag-and-drop support for ListViews provided by our beloved WPF guru, Josh Smith. So, with Josh's blessing, I set out to adapt his ListViewDragDropManager into a TreeViewDragDropManager. It was a lengthy learning process, but I'm happy to say that the port is complete and a robust solution for TreeView DnD is now available. To demonstrate this functionality, the download contains a modified version of "Demo 2" from my Code Project article.

Although many of the private helpers and event handlers in my port differ significantly from the original, the public interface remains nearly identical. So you can read Josh's article, the "Using the code" section in particular, to get started. But do note the differences. First, my class takes two type parameters (instead of one), which you can best understand in the context of my Code Project article. Second, whereas Josh's ProcessDrop event is optional, my class requires you to subscribe in order to actually move a dropped item.

The drag-and-drop setup code in the demo look like this:
var m = new TreeViewDragDropManager<SampleTreeNode, SampleTreeNodeView>( sampleTreeView );
m.ProcessDrop += delegate( object sender, ProcessDropEventArgs<SampleTreeNode> e ) {
e.DroppedItem.ParentNode = null; //move the selected item
e.NewParent.SubNodes.Insert( e.NewIndex, e.DroppedItem );
};

Thursday, September 18, 2008

Visa run by bicycle

A fact of life for many foreigners staying long term in Thailand, and in other countries probably, is the visa run. My visa is valid for one year, but I'm only allow to stay continuously for a maximum of ninety days. Before exceeding that limit I must leave Thailand, even if for just five minutes before returning again.

So today it was visa run time again! Well, my ninety days wasn't up until Monday, but I decide to get it over with a few days early. I arrived yesterday in this town on the Burmese border, called Mae Sot. I came from Lampang where I was visiting some American friends. I didn't depart there until 1pm, however, so I arrived in Mae Sot at 5pm. I headed straight to the border. When I got there at 5:11pm I found out the Burmese side closes at 5pm. Oops.

I headed into town where I eventually found the decent and affordable Green Guest House. It's located on a side-street behind the police station, just past the holding facility (just a big cage really) for illegal Burmese immigrants. After checking in, I went to eat dinner at the restaurant Krua Canadian (Canadian Kitchen) which (surprise!) is owned and operated by a Canadian guy with a Thai wife. It was good tasting Mexican food, better than what I had in Chiang Mai. I assume the Canadian owner spent some time living in Mexico before coming to Thailand.

This morning I rented one of the guest house's bicycles, then rode the five kilometers or so to the border. I took a bunch of photos, with the idea in mind to write this blog entry tonight. So here the photos are below.

The day's mode of transporation, in front of the guest house


The road ahead


The road ahead becomes a four-lane highway


Border checkpoint in sight


For some, this is the way home


Crossing the bridge into Burma


Some Burmese don't need a bridge, or travel documents, to get into Thailand


The Burmese end of the bridge is in sight


I spent a couple minutes walking down the street


Then into some market... (then I headed back to Thailand)

Sunday, August 24, 2008

Item Presentation Models for WPF

After two weeks of work (and some play), I've finally posted my Item Presentation Models for WPF article to Code Project. This is my first Code Project article ever, so I'm excited about it. I hope readers find it useful and I look forward to their feedback.

Tuesday, August 19, 2008

Naming domain-specific ItemPresentationModel objects

Outside the scope of MVC-related design patterns, the word "view" has a more general meaning that's applied in varying contexts. SQL, for example, uses it to mean a derived view of base data. Closer to the present topic, WPF includes the CollectionView class which is a sort of presentation-model. People who prefer that "view" strictly refer to the UI probably hate this choice of class name. However, appending "ViewModel" or the even longer "PresentationModel" to all my class names is verbose in my opinion.

For the above reasons I instead use the suffix "View" as an acceptably short alternative for my domain-specific Presentation Model classes. By doing so, I intend to invoke the word's general meaning of the sense that the presentation-model provides a derived view of the domain object. Another interpretation is that the presentation-model provides an interface for the domain object that makes it fit for presentation; the presentation-model is therefore an abstract view (presentation) object. This latter interpretation is useful since it emphasises the presentation-model's actual purpose, which is that it facilitates visual display (in that sense, Josh Smith's original "Presenter" suffix doesn't sound half bad).

I am aware that this naming breaks away from every quasi-standard in the literature of MVC and its derivatives. Even the WPF library doesn't use it consistently. That is, they use the word "View" in its more traditional sense as well, as in ListView and TreeView. If instead WPF named those controls "ListControl" and "TreeControl" — which would be consistent with many other controls in their library such as ContentControl, ItemsControl, UserControl, and TabControl — then I would find their choice of "CollectionView" more acceptable. In any case, I still find their suffix "View" to be so much more aesthetically pleasing than the alternatives, so that's what I choose to use in my own projects. Such a choice, however, has implications only within the scope of individual projects or organisations. Therefore, others can use whatever naming convention they find to be the easiest to live with.