Monday, January 31, 2011

Cool strings: Kanon Wakeshima and Emilie Autumn

Kanon Wakeshima has a cool cello and voice song, taken from the soundtrack of an anime, of course, but still, a pretty cool song: Kanon Wakeshima - Suna No Oshiro




Emilie Autumn
has some really nice instrumental songs, like the one I put here, and some nice voice songs. Unfortunately I don't like the instrumentation of the voice songs. I am still looking for a perfect crazy electric violin and voice song, but it may be that singing and playing the violin is impossible or at least too difficult. So here is Emilie Autumn - Manic Depression:

Unlimited unpolluting cheap gasoline?

It appears that a British project, secretly conducted by the Rutherford Appleton Laboratory, has produced a method of encapsulating hydrogen into microparticles of porous material. The result is something that acts like a liquid, burns like hydrogen and can be used inside normal cars without any engine modification. The price they propose is 1.5$ per gallon, which is 0.396$ per liter or 0.2915 euros. What is cool about it is that they don't need to extract any resource in order to produce this miracle fuel.

Could THIS be the end of oil? Frankly I am amazed that this news reached me and not the one about Stephen Bennington found dead in a ditch somewhere. I can only hope that the secrecy of the project paid off and that the guys at Cella Energy have really managed to find the solution while under the radar of Big Oil. Or maybe it is simply the time in which the dependency on oil has become a bigger threat to national security than the lack of funding coming from oil companies.

Link to the original news: Breakthrough promises $1.50 per galon synthetic gasoline with no carbon emissions

Update: I may have spoken too soon. A NewScientist article explains the process in a slightly different light. The beads do store hydrogen, but they must be heated in order to release that hydrogen, then the hydrogen would be used in fuel cells. That is at odds with the idea that you can use it as gasoline in a petrol tank car. Oh, well, I hope they get it right someday.

Monday, January 24, 2011

Religious texts (List of Wikipedia)

Another interesting List of Wikipedia is the list of religious texts. It's a medium sized list, although I suspect it is not nearly complete and that some of the works there are pretty big.

I am not much on religion, but I wonder what one would come to think of if presented with all the texts in the list, exposed to them without any cultural bias. Would some sort of distilation of the concept of religion emerge from it, or would everybody just choose a religion they feel more comfortable with? Or maybe they would write their own religious texts.

When I think about it, I can't help but compare it with the emergence of certain genres in fiction, like alien invasion sci-fi or comic book super heroes. First there are some original authors that come up with an idea. The idea is well liked, bought and distributed. It becomes well known so that other people start making work of their own that is inspired by that. It's almost organic, with reproduction, mutation, cross breeding and extinction. However, the integrity of religions is mostly enforced by communities of people that insist on changing nothing. They stop evolution, but also protect against extinction. Is stagnation the hallmark of religion or is it the stability that it provides in a world in continuous flux of change?

I will tell you this: I like evolution. And I mean it in the most general sense, not only the Darwinian one. I find it ironic that in my mind religion is the opposite of evolution. Or maybe that's a cultural bias. Hmm...

Saturday, January 22, 2011

Shigurui, one of the most beautiful manga/anime I've seen

the two swordsmenThe Shigurui (Death Frenzy) manga is now complete. The beautifully terrible story of two exceptional samurai in a world of politics, betrayal and cultural conditioning, locked in absolute rivalry, has ended with the 84th chapter, Pure Crimson. There is an anime with the same subject, I've also seen it and it is really great, even if it stops dead after 11 episodes. I actually recommend to watch the anime and then continue with the chapters in the manga, in order to understand better the feeling of the story. It must be said that the translation from a book written by a war veteran to a graphic novel by a mangaka 58 years his young and then translated to TV anime has not lost, but gained insight and emotion.

One can read the entire manga at MangaFox.

Tuesday, January 18, 2011

List of Misconceptions!

I've never thought to check if there is such a list on the Internet, but apparently it is, as described in the xkcd comic. Good thing I at least read that! Wikipedia's List of common misconceptions is a very interesting read, many of the myths described there being reedited regularly through the media without them actually being true! So, get reading.

Monday, January 17, 2011

How to hide inherited members on MSDN pages

If you are like me, you often google a .Net class and find it at MSDN. Also, since you want the page to load quickly and get you the information you need, you probably selected the Lightweight view on MSDN. If you haven't, you should :) Anyway, a problem with MSDN is that it shows you every possible member of the class, which is especially annoying with WPF classes as they inherit from FrameworkElement that has a gazillion events. Wouldn't it be great if one could hide the inherited members from an MSDN page?

At first I thought I would parse the content of each row and detect the (Inherited from string, but it appears it is even simpler: table row elements have a data attribute that (if the member is inherited) contains the word inherited. Probably someone at MSDN wanted to make the same thing as me, but forgot to implement it (at least on the lightweight view). The javascript is simple enough:

var trs=document.getElementsByTagName('tr');
var l=trs.length;
for (var i=0; i<l; i++) {
var tr=trs[i];
var data=tr.getAttribute('data');
if (!data||data.indexOf('inherited')==-1) continue;
tr.style.display=tr.style.display=='none'?'':'none';
}
You probably wonder why I haven't used jQuery. It is because I want it to work in a javascript: url so I can put it in a bookmark! Just as with the Firebug bookmark you need to manually create a bookmark in the Favorites folder (or to add any page as a favorite, then edit its URL) in Internet Explorer or to simply add a bookmark in the browser in Chrome and Firefox and paste the one line script. To make it easier, I will write them both here. The content of the .url favorite file:
[DEFAULT]
BASEURL=http://msdn.microsoft.com/en-us/library/
[InternetShortcut]
URL=javascript:var trs=document.getElementsByTagName('tr');var l=trs.length;for (var i=0; i<l; i++) { var tr=trs[i]; var data=tr.getAttribute('data'); if (data&&data.indexOf('inherited')>-1) tr.style.display=tr.style.display=='none'?'':'none'; }; void(0);
IDList=
IconFile=http://msdn.microsoft.com/favicon.ico
IconIndex=1
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
and the javascript line to use in other browsers:
javascript:var trs=document.getElementsByTagName('tr');var l=trs.length;for (var i=0; i<l; i++) {  var tr=trs[i];  var data=tr.getAttribute('data');  if (data&&data.indexOf('inherited')>-1)  tr.style.display=tr.style.display=='none'?'':'none'; }; void(0);
.

Happy coding!

Saturday, January 15, 2011

Dexter is Delicious by Jeff Lindsay

book coverThe fifth book in the Dexter Morgan series by Jeff Lindsay, Dexter is Delicious is slightly better written than the first four, but also less credible. The main character is torn between his Dark Passanger and the desire to love and protect his newly born child. He thus decides to "become human" in the worst possible moment. His brother Brian, who attempted to kill Dexter's adoption sister Deborah, also makes an appearance. The bad guys in the story are a cannibal ring and they are quite the gourmet, requiring Dexter as a main course.

The problem with this book, apart from the general Dexter Morgan hard to swallow leaps of faith, is that the Dark Passenger is pushed back, as Dexter gets in tough with his parental instincts. For me, at least, Dark-Dexter was the main character and the mischievous whispers of his inner demon were the delight of the series. If I would want to know people having kids and loving their pinkness I would read something else entirely.

I will continue to follow the series, but I can't help feeling a little dissappointed every time I read one of the books in the series. With such a wonderful subject, the possibilities are limitless and a great deal of potential wasted.

Friday, January 14, 2011

Another take on INotifyPropertyChanged generation from POCO Objects

The latest sources are now on CodePlex: C# 4.0 library to generate INotifyPropertyChanged proxy from POCO type. The source from the post, designed as a proof of concept, is not the same as the one from CodePlex.

It all started from a Sacha Barber post on CodeProject, enumerating ways in which one can use Aspect Oriented Programming to mark simple automatic properties so that they get compiled into fully fledged INotifyPropertyChanged properties, thus saving us the grief of repeating the same code over and over again in each property setter. The implementations there were good, but too complex, relying on third party libraries, some of them not even free.
He completely ignored template generators like T4, but then again, that particular approach has a lot of issues associated with it, like having to either parse source files or somehow tap into the compiled assembly... before you compile it.
However, this brought forth the idea that I could do this, maybe in some other way.

Enter Felice Pollano, with his article on CodeProject detailing a method of using CodeDom generation to create at runtime the INotifyPropertyChanged object from an already existing type. This is pretty slow, but only when first creating the type, so with a cache system it would be totally usable. I liked this approach better, but I noticed there were some errors in the generated code and when I tried changing the generating code I had to look at it for half an hour just to understand where to change it. Wouldn't it be better to use some sort of template that would be easy to edit and use it to generate the proxy type?

So this is my take on generating INotifyPropertyChanged classes dynamically, avoiding the repetitive plumbing in property setters. The library contains a template for the class and a separate template for the properties. The proxy type is being generated in memory from a string that is generated from the source type and the two templates. All in all, one class, two templates, three public methods and four static methods. As easy as 1,2,3,4 :) Here is the code:
Click to expand/collapse

public static class TypeFactory
{
private static readonly Dictionary<Type, Type> sCachedTypes = new Dictionary<Type, Type>();

public static T GetINotifyPropertyChangedInstance<T>(params object[] arguments)
{
Type type = GetINotifyPropertyChangedType<T>();
return (T) Activator.CreateInstance(type, arguments);
}

public static Type GetINotifyPropertyChangedType<T>()
{
return GetINotifyPropertyChangedType(typeof (T));
}

public static Type GetINotifyPropertyChangedType(Type type)
{
Type result;
lock (((ICollection) sCachedTypes).SyncRoot)
{
if (!sCachedTypes.TryGetValue(type, out result))
{
result = createINotifyPropertyChangedProxyType(type);
sCachedTypes[type] = result;
}
}
return result;
}

public static bool IsVirtual(this PropertyInfo info)
{
return (info.CanRead == false || info.GetGetMethod().IsVirtual)
&&
(info.CanWrite == false || info.GetSetMethod().IsVirtual);
}


private static Type createINotifyPropertyChangedProxyType(Type type)
{
var className = "@autonotify_" + type.Name;
var properties = type.GetProperties().Where(p => p.IsVirtual());
var sourceCode = getINotifyPropertyChangedSourceCode(className, type, properties);
var assembly = generateAssemblyFromCode(sourceCode);
return assembly.GetTypes().First();
}

private static string getINotifyPropertyChangedSourceCode(string className, Type baseType,
IEnumerable<PropertyInfo> properties)
{
var classTemplate = getTemplate("INotifyPropertyChangedClassTemplate.txt");
var propertyTemplate = getTemplate("INotifyPropertyChangedPropertyTemplate.txt");
var usingsBuilder = new StringBuilder();
var propertiesBuilder = new StringBuilder();
usingsBuilder.AppendLine("using System.ComponentModel;");
usingsBuilder.AppendFormat("using {0};\r\n", baseType.Namespace);
foreach (PropertyInfo propertyInfo in properties)
{
usingsBuilder.AppendFormat("using {0};\r\n", propertyInfo.PropertyType.Namespace);

string propertyString = propertyTemplate
.Replace("{propertyType}", propertyInfo.PropertyType.FullName)
.Replace("{propertyName}", propertyInfo.Name);
propertiesBuilder.AppendLine(propertyString);
}
string sourceCode = classTemplate
.Replace("{usings}", usingsBuilder.ToString())
.Replace("{className}", className)
.Replace("{baseClassName}", baseType.Name)
.Replace("{properties}", propertiesBuilder.ToString());
#if DEBUG
Debug.WriteLine(sourceCode);
#endif
return sourceCode;
}

private static string getTemplate(string resourceName)
{
var templateAssembly = Assembly.GetAssembly(typeof (TypeFactory));
resourceName = templateAssembly.GetManifestResourceNames()
.First(name => name.EndsWith(resourceName));
using (Stream stream = templateAssembly.GetManifestResourceStream(resourceName))
{
using (var streamReader = new StreamReader(stream))
{
return streamReader.ReadToEnd();
}
}
}

private static Assembly generateAssemblyFromCode(string sourceCode)
{
var codeProvider = CodeDomProvider.CreateProvider("CSharp");
var parameters = new CompilerParameters
{
GenerateExecutable = false,
GenerateInMemory = true
};
var locations = AppDomain.CurrentDomain.GetAssemblies()
.Where(v => !v.IsDynamic).Select(a => a.Location).ToArray();
parameters.ReferencedAssemblies.AddRange(locations);
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, sourceCode);
#if DEBUG
foreach (CompilerError error in results.Errors)
{
Debug.WriteLine("Error: " + error.ErrorText);
}
#endif
return results.Errors.Count > 0
? null
: results.CompiledAssembly;
}
}

As you can see, the code needs only a type that has public virtual properties in it and it will create a proxy that will inherit that class, implement INotifyPropertyChange and override each virtual property with a notifying one. The templates are so basic that I feel slightly embarrassed; I keep thinking if I should have created template entities that would stay in the same file. :) Here are the templates:

{usings}

namespace __generatedINotifyPropertyChanged
{
public class {className} : {baseClassName},INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

{properties}

private void OnPropertyChanged(string propertyName)
{
var handler=PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

public override {propertyType} {propertyName}
{
get { return base.{propertyName}; }
set {
if (!Equals(value,base.{propertyName})) {
base.{propertyName}=value;
OnPropertyChanged("{propertyName}");
}
}
}


Don't forget to save the templates as Embedded Resource in the assembly.

Update: At Sacha Barber's advice I took a look at the DynamicObject solution for the INotifyPropertyChanged code smell. The link he provided is OlliFromTor's CodeProject article Using DynamicObject to Implement General Proxy Classes. While this works a lot easier than with compiling generated code, it also has a major drawback: the proxy class does not inherit from the original object and so it can only be used as such, but only in dynamic scenarios. Otherwise, it seems to be a perfect solution for proxy scenarios, if you are willing to discard the type safety.

Wednesday, January 12, 2011

aspnet_wp.exe could not be started (error C0000142)

I restarted my computer and afterwards I could not access any of the local sites via IIS. The error message in the Application logs of the EventViewer was
Event Type: Error
Event Source: ASP.NET 4.0.30319.0
Description:
aspnet_wp.exe could not be started. The error code for the failure is C0000142. This error can be caused when the worker process account has insufficient rights to read the .NET Framework files. Please ensure that the .NET Framework is correctly installed and that the ACLs on the installation directory allow access to the configured account.
I did the classic
iisreset /stop
%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i
iisreset /start
to no avail. I was about to curse and restart the computer again when I found this pretty little link: IIS doesn't start. Error code: C0000142. A solution is at the bottom, as the least voted answer: Go to Task Manager, kill explorer.exe, Run another explorer.exe. This starts IIS (aspnet_wp.exe under inetinfo.exe) correctly.

Update: It bugged me that I had to kill explorer.exe. First of all it is a manual solution, then it always messed with my system tray icons. So I searched a little more. Short story shorter, you need to edit machine.conf and replace <processModel autoConfig="true" /> with <processModel userName="system" password="AutoGenerate" />. That effectively makes ASP.Net work under the System account, not the default machine. It does indicate the issue is permission related, but I don't get exactly where and why it should work if I restart explorer.exe. As long as you don't mind running ASP.Net under the System account, this solution seems to solve it. Here is the long version.

Note: you can find the machine.config file in %windir%\Microsoft.NET\Framework\[framework version]\Config\machine.config.

Monday, January 10, 2011

Firebug in any browser!

I personally think that the IE8 developer tools are better than Firebug, but let's face it: Firebug was first. Besides, Firebug has also a completely javascript version called Firebug lite that you can inject into any page. Well, you might say, as a developer it is a nice tool, but how can I, the Internet surfer, use this in any page? And the answer is: the favorites links!

It all started from this brilliant post: Bookmark to inject FireBug Light into Internet Explorer. that showed how you can create a specific URL file, add it to the Favorites folder of your Windows user and then use it on any page. Elegant it may be, but it's lazy. It only works on pages that have loaded jQuery. So I did the version that works with simple javascript.

Then I realized that, since I like the Internet Explorer tools better, this is useless for me. How cool would it be to have Firebug lite on Chrome, which has yet to provide a decent developer tool. And it's even easier! Here is how you do it.

For Internet Explorer, follow the steps described in the ElegantCode post but use generic javascript: create a file called Firebug.url containing
[DOC_FirebugUI] 
ORIGURL=about:blank
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
URL=javascript:var script=document.createElement('script'); script.type='text/javascript'; script.src='https://getfirebug.com/firebug-lite.js';document.getElementsByTagName('body')[0].appendChild(script); void(0);
IDList=
IconFile=http://getfirebug.com/img/favicon.ico
IconIndex=1
then save it in the user's c:\Documents and Settings\{UserName}\Favorites folder.

For Chrome, you only right click on the bookmarks bar, choose Add Page, then enter the url in the file above:
javascript:var script=document.createElement('script'); script.type='text/javascript'; script.src='https://getfirebug.com/firebug-lite.js';document.getElementsByTagName('body')[0].appendChild(script); void(0);

And that is it. Click on the link in any of the said browsers and a small icon will appear in the bottom-right corner. Click on it and voila: Firebug! Of course, one can install the Firebug extension, which is actually also a javascript link, albeit really weird, but I think this is more clear and user friendly.

Tuesday, January 04, 2011

MVVM Drag and Drop

When I first tried to do drag and drop in WPF I thought it would be something easy like DragAndDrop.IsDraggable="True". Boy,was I wrong! The mechanism for this has remained almost unchanged from the Windows Forms version. It is completely event driven and has nothing in the way of actual graphical feedback of what is going on except making the mouse cursor look different. If you want to do it using MVVM, you have another thing coming.

Disclaimer:Now, I have found a good solution for all the problems above, but the drag and drop behaviour is part of a larger framework that I have been working on and creating a separate project just for it might prove difficult. I mean, you want to show MVVM drag and drop, you should also have Views and ViewModels and base classes and helpers and everything. The solution, I guess, is to make separate articles for the main features in the framework, then present the project as a whole in the end. The framework itself is work in progress and untested in a real life project, so this might have to wait, as well. I will make sure, though, to put much code directly in this post.

First a bit of thanks to the people that inspired me to work on that. I have Sascha Barber to thank for his comprehensive articles on WPF, especially the ones about his Cinch framework. Then Lee Roth and Bea Stollnitz/Costa for the ideas about using adorners to show the drag and drop items. Finally Jason Young, for writing about MVVM Drag and Drop, but without the graphic part.

Ok then, let's define the requirements of this system. We need:
  • A drag item
  • A drop target
  • Showing the target is being dragged
  • Showing the target can or cannot be dropped
  • Showing the item being dragged
  • Changing the appearance of the original dragged element while dragging
  • Changing the appearance of the drop target while dragging something over
  • Allowing for drag and drop between Windows
  • Allowing for drag and drop between applications
  • Changing an application that works but has no drag and drop in an easy and maintainable way
  • Using as simple a system as possible
  • Doing everything using the Model-View-ViewModel pattern

From these requirements we can form a basic idea of the way we would like this to work. First of all, we need the ability to mark any element as a drag item. Also, we need a container that can be marked as a drop target. We can do this using boolean IsDragSource and IsDropTarget Attached Properties; once set they will force a bind of the drag and drop events to some special handlers that would then direct decisions to ICommands.

As we are doing it in MVVM, we don't use the elements directly, but the data they represent, so we work with dragging and dropping commands using data objects. The classes responsible with the decisions for the drop permissions and actions should be in the ViewModel. We could, of course, link all events to commands, but that would be very cumbersome to use. Besides, we want it simple, we don't really want the user of the system to care about the drag and drop inner workings. Therefore, the solution is to change the IsDragSource and IsDropTarget to DragSource and DropTarget properties that accept objects of type IDragSource and IDropTarget containing all the methods needed for the events in question:

/// <summary>
/// Holds the data of a dragged object in a drag-and-drop operation.
/// </summary>
public interface IDraggedData
{
/// <summary>
/// A dictionary with the format as the key and the data in that format in the value
/// </summary>
IDictionary<string, object> Values
{
get;
}

/// <summary>
/// Optional object for additional information
/// </summary>
object Tag
{
get;
}
}

/// <summary>
/// Business end of the drag source
/// </summary>
public interface IDragSource
{
/// <summary>
/// Gets the supported drop effects.
/// </summary>
/// <param name="dataContext">The data context.</param>
/// <returns></returns>
DragEffects GetDragEffects(object dataContext);

/// <summary>
/// Gets the data.
/// </summary>
/// <param name="dataContext">The data context.</param>
/// <returns></returns>
object GetData(object dataContext);
}

/// <summary>
/// Defines the handler object of a drop operation
/// </summary>
public interface IDropTarget
{
/// <summary>
/// Gets the effects.
/// </summary>
/// <param name="dataObject">The data object.</param>
/// <returns></returns>
DragEffects GetDropEffects(IDraggedData dataObject);

/// <summary>
/// Drops the specified data object
/// </summary>
/// <param name="dataObject">The data object.</param>
void Drop(IDraggedData dataObject);
}
We need the methods for the effects to instruct the system about the types of operations that are allowed during drag and drop: None, Copy, Move, Scroll, All.

If you are going for the purist approach, you should use your own DragEffects enumeration, as above, since the DragDropEffects enumeration is in the System.Windows assembly, which in theory should have nothing to do with the ViewModel part of the application (one could want to use the ViewModel in a web environment, for example, or in a console application).

You will notice that the GetDropEffects method receives an IDraggedData object. This is also because the IDataObject interface and the DataObject class used in Windows drag and drop operations are also in the System.Windows assembly.

The IDraggedData interface is basically a dictionary that uses the data format as the key and the dragged data object stored in that format as the value. An important fact is that, when trying to drag and drop between applications, you need that the dragged data object be binary serializable. If not, you will only get the expected result when dragging to the same application. Here is an implementation of the interface, complete with a totally lazy way of getting the data based on which type is more "important":

/// <summary>
/// Holds data for a drag-and-drop operation
/// </summary>
public class DraggedData : IDraggedData
{
#region Instance fields

private Dictionary<string, Exception> mExceptions;
private Dictionary<string, object> mValues;

#endregion

#region Properties

/// <summary>
/// A dictionary with the format as the key and the data in that format in the value
/// </summary>
/// <value></value>
public Dictionary<string, object> Values
{
get
{
if (mValues == null)
{
mValues = new Dictionary<string, object>();
}
return mValues;
}
}

/// <summary>
/// A dictionary with the format as the key and the data in that format in the value
/// </summary>
/// <value></value>
IDictionary<string, object> IDraggedData.Values
{
get
{
return Values;
}
}

/// <summary>
/// Optional object for additional information
/// </summary>
/// <value></value>
public object Tag
{
get;
set;
}

/// <summary>
/// A dictionary for exceptions when retrieving the data in a specified format
/// </summary>
/// <value>The exceptions.</value>
public Dictionary<string, Exception> Exceptions
{
get
{
if (mExceptions == null)
{
mExceptions = new Dictionary<string, Exception>();
}
return mExceptions;
}
}

#endregion
}
In the IDragSource interface we need the GetData method to extract the data object associated with a dragged object, since the Windows drag and drop mechanism encapsulates the objects in an application agnostic way, so one can perform drag and drop between applications or to/from the operating system. Finally, we need the Drop method in the IDropTarget interface to handle in the ViewModel what happends when an item is dropped.

Let's get to the juicy part: a DragService static class that will register the attached properties that we need. Besides the DragSource and DropTarget properties we need status properties like DragOverStatus (for the target), DraggedStatus and IsDragged (for the original dragged item) as well as two properties called BringIntoViewOnDrag and ActivateOnDrag which would bring an item completely into view or activate it (if a Window) when a valid drop target. This one is long. It also contains some extension methods that would be explained later.

Click to expand/collapse

/// <summary>
/// Holds attached properties related to drag-and-drop operations
/// </summary>
public static class DragService
{
#region Static Instance fields

/// <summary>
/// Property for the behaviour to activate a window when something is dragged over it
/// </summary>
public static readonly DependencyProperty ActivateOnDragProperty
= DependencyProperty.RegisterAttached(
"ActivateOnDrag",
typeof (bool), typeof (DragService),
new FrameworkPropertyMetadata(
false)
);

/// <summary>
/// Property for the behaviour to bring into view an element when something is dragged over it
/// </summary>
public static readonly DependencyProperty BringIntoViewOnDragProperty
= DependencyProperty.RegisterAttached(
"BringIntoViewOnDrag",
typeof (bool), typeof (DragService),
new FrameworkPropertyMetadata(
false)
);

/// <summary>
/// Property for the status of a drag-over operation
/// </summary>
public static readonly DependencyProperty DragOverStatusProperty
= DependencyProperty.RegisterAttached(
"DragOverStatus",
typeof (DragEffects), typeof (DragService),
new FrameworkPropertyMetadata(DragEffects.None)
);

/// <summary>
/// Property for the handler of drag-source operations
/// </summary>
public static readonly DependencyProperty DragSourceProperty
= DependencyProperty.RegisterAttached(
"DragSource",
typeof (IDragSource), typeof (DragService),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(dragSourceChanged))
);

/// <summary>
/// Property for the drag status of a drag source
/// </summary>
public static readonly DependencyProperty DragStatusProperty
= DependencyProperty.RegisterAttached(
"DragStatus",
typeof (DragEffects), typeof (DragService),
new FrameworkPropertyMetadata(DragEffects.None)
);

/// <summary>
/// Property for the handler of drop-target operations
/// </summary>
public static readonly DependencyProperty DropTargetProperty
= DependencyProperty.RegisterAttached(
"DropTarget",
typeof (IDropTarget), typeof (DragService),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(dropTargetChanged)));

/// <summary>
/// True if element is part of the content displayed while dragging
/// </summary>
public static readonly DependencyProperty IsDraggedProperty
= DependencyProperty.RegisterAttached(
"IsDragged",
typeof (bool), typeof (DragService),
new FrameworkPropertyMetadata(false)
);

private static DependencyObject sDraggedDependencyObject;
private static Point? sStartPoint;

#endregion

#region Static Public Methods

///<summary>
/// Attached getter method for DragOverStatus
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static DragEffects GetDragOverStatus(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (DragEffects) element.GetValue(DragOverStatusProperty);
}

///<summary>
/// Attached setter method for DragOverStatus
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetDragOverStatus(DependencyObject element, DragEffects value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(DragOverStatusProperty, value);
}

///<summary>
/// Attached getter method for DragStatus
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static DragEffects GetDragStatus(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (DragEffects) element.GetValue(DragStatusProperty);
}

///<summary>
/// Attached setter method for DragStatus
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetDragStatus(DependencyObject element, DragEffects value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(DragStatusProperty, value);
}

///<summary>
/// Attached getter method for IsDragged
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static bool GetIsDragged(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool) element.GetValue(IsDraggedProperty);
}

///<summary>
/// Attached setter method for IsDragged
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetIsDragged(DependencyObject element, bool value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(IsDraggedProperty, value);
}

/// <summary>
/// Try to get the dragged data in its most qualified format:
/// something not null and not string, string, anything else, null
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static object GetBestDraggedDataObject(DragEventArgs e)
{
DraggedData draggedData = getData(e);
object data = null;
foreach (KeyValuePair<string, object> pair in draggedData.Values)
{
object value = pair.Value;
if (value == null)
{
continue;
}
if (data == null)
{
data = value;
continue;
}
if ((data is string) && !(value is string))
{
data = value;
break;
}
}
return data;
}

///<summary>
/// Attached getter method for DropTarget
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static IDropTarget GetDropTarget(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (IDropTarget) element.GetValue(DropTargetProperty);
}

///<summary>
/// Attached setter method for DropTarget
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetDropTarget(DependencyObject element, IDropTarget value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(DropTargetProperty, value);
}

///<summary>
/// Attached getter method for DragSource
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static IDragSource GetDragSource(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (IDragSource) element.GetValue(DragSourceProperty);
}

///<summary>
/// Attached setter method for DragSource
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetDragSource(DependencyObject element, IDragSource value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(DragSourceProperty, value);
}

///<summary>
/// Attached getter method for BringIntoViewOnDrag
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (FrameworkElement))]
public static bool GetBringIntoViewOnDrag(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool) element.GetValue(BringIntoViewOnDragProperty);
}

///<summary>
/// Attached setter method for BringIntoViewOnDrag
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetBringIntoViewOnDrag(DependencyObject element, bool value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(BringIntoViewOnDragProperty, value);
}

///<summary>
/// Attached getter method for ActivateOnDrag
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static bool GetActivateOnDrag(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool) element.GetValue(ActivateOnDragProperty);
}

///<summary>
/// Attached setter method for ActivateOnDrag
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetActivateOnDrag(DependencyObject element, bool value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(ActivateOnDragProperty, value);
}

#endregion

#region Static Private Methods

private static void dropTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UIElement element = (UIElement) d;

if (e.NewValue != null)
{
registerDropTarget(element);
}
else
{
unregisterDropTarget(element);
}
}

private static void unregisterDropTarget(UIElement element)
{
element.DragOver -= dragOver;
element.DragLeave -= elementDragLeave;
element.Drop -= drop;
element.AllowDrop = false;
}

private static void registerDropTarget(UIElement element)
{
element.DragOver += dragOver;
element.DragLeave += elementDragLeave;
element.Drop += drop;
element.AllowDrop = true;
element.ExecuteWhenUnloaded(() => unregisterDropTarget(element));
}

private static void elementDragLeave(object sender, DragEventArgs e)
{
DependencyObject dependencyObject = (DependencyObject) sender;
SetDragOverStatus(dependencyObject, DragEffects.None);
}

private static void drop(object sender, DragEventArgs e)
{
DependencyObject dependencyObject = (DependencyObject) sender;
IDropTarget dropTarget = GetDropTarget(dependencyObject);
DraggedData data = getData(e);
dropTarget.Drop(data);
SetDragOverStatus(dependencyObject, DragEffects.None);
e.Handled = true;
}

private static DraggedData getData(DragEventArgs e)
{
DraggedData data = new DraggedData();
string[] formats = e.Data.GetFormats(false);
foreach (string format in formats)
{
try
{
data.Values[format] = e.Data.GetData(format);
}
catch (Exception ex)
{
data.Values[format] = null;
data.Exceptions[format] = ex;
}
}
return data;
}

private static void dragOver(object sender, DragEventArgs e)
{
DependencyObject dependencyObject = (DependencyObject) sender;
IDropTarget dropTarget = GetDropTarget(dependencyObject);

DraggedData data = getData(e);
DragEffects dragEffects = dropTarget.GetDropEffects(data);
e.Effects = getEffects(dragEffects);
if (sDraggedDependencyObject != null)
{
SetDragStatus(sDraggedDependencyObject, dragEffects);
}
SetDragOverStatus(dependencyObject, dragEffects);

e.Handled = true;
if (GetActivateOnDrag(dependencyObject))
{
Window window = Window.GetWindow(dependencyObject);
if (window != null && !window.IsActive)
{
window.Activate();
}
}
if (GetBringIntoViewOnDrag(dependencyObject))
{
FrameworkElement element = dependencyObject as FrameworkElement;
if (element != null)
{
element.BringIntoView();
}
}
}

private static DragDropEffects getEffects(DragEffects effects)
{
DragDropEffects result;
return Enum.TryParse(effects.ToString(), out result)
? result
: (DragDropEffects) (int) effects;
}

private static void dragSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UIElement element = (UIElement) d;
if (e.NewValue != null)
{
registerDragItem(element);
}
else
{
unregisterDragItem(element);
}
}

private static void unregisterDragItem(UIElement element)
{
element.PreviewMouseLeftButtonDown -= previewMouseLeftButtonDown;
element.PreviewMouseMove -= previewMouseMove;
element.MouseLeave -= mouseLeave;
element.QueryContinueDrag -= elementQueryContinueDrag;
element.GiveFeedback -= elementGiveFeedback;
}

private static void registerDragItem(UIElement element)
{
element.PreviewMouseLeftButtonDown += previewMouseLeftButtonDown;
element.PreviewMouseMove += previewMouseMove;
element.MouseLeave += mouseLeave;
element.QueryContinueDrag += elementQueryContinueDrag;
element.GiveFeedback += elementGiveFeedback;
element.ExecuteWhenUnloaded(() => unregisterDragItem(element));
}

private static void elementGiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (sDraggedDependencyObject != null)
{
DragEffects dragDropEffects = getDragDropEffects(e.Effects);
SetDragStatus(sDraggedDependencyObject, dragDropEffects);
}
}

private static DragEffects getDragDropEffects(DragDropEffects effects)
{
DragEffects result;
return Enum.TryParse(effects.ToString(), out result)
? result
: (DragEffects) (int) effects;
}

private static void elementQueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
if (!e.KeyStates.HasFlag(DragDropKeyStates.LeftMouseButton))
{
DependencyObject dependencyObject = sender as DependencyObject ?? sDraggedDependencyObject;
endDrag(dependencyObject);
}
}

private static void endDrag(DependencyObject dependencyObject)
{
if (dependencyObject == null)
{
return;
}
SetIsDragged(dependencyObject, false);
if (sDraggedDependencyObject != null)
{
SetDragStatus(sDraggedDependencyObject, DragEffects.None);
}
sDraggedDependencyObject = null;
}

private static void mouseLeave(object sender, MouseEventArgs e)
{
sStartPoint = null;
}

private static void previewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed || sStartPoint == null)
{
return;
}

if (!hasMouseMovedFarEnough(e))
{
return;
}

FrameworkElement dependencyObject = (FrameworkElement) sender;
object dataContext = dependencyObject.GetValue(FrameworkElement.DataContextProperty);
IDragSource dragSource = GetDragSource(dependencyObject);

DragDropEffects dragDropEffects = getEffects(dragSource.GetDragEffects(dataContext));
if (dragDropEffects == DragDropEffects.None)
{
return;
}
startDrag(dependencyObject);
DragDrop.DoDragDrop(dependencyObject,
getDraggedData(dragSource, dataContext),
dragDropEffects);
}

private static void startDrag(DependencyObject dependencyObject)
{
SetIsDragged(dependencyObject, true);
sDraggedDependencyObject = dependencyObject;
}

private static object getDraggedData(IDragSource dragSource, object dataContext)
{
object data = dragSource.GetData(dataContext);
DataObject dataObject = new DataObject();
if (data != null)
{
if (!SerializationHelper.IsBinarySerializable(data))
{
DebugHelper.Warn(
"Trying to drag a DataItem that cannot be binary serialized. It will not work across applications");
}
dataObject.SetData(DataFormats.Text, data.ToString());
string typeName = data.GetType().FullName;
if (typeName != null)
{
DataFormat format = DataFormats.GetDataFormat(typeName);
dataObject.SetData(format.Name, data);
}
}
return dataObject;
}

private static void previewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
sStartPoint = e.GetPosition(null);
}

private static bool hasMouseMovedFarEnough(MouseEventArgs e)
{
if (sStartPoint == null)
{
return false;
}
Vector delta = sStartPoint.GetValueOrDefault() - e.GetPosition(null);

return Math.Abs(delta.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(delta.Y) > SystemParameters.MinimumVerticalDragDistance;
}

#endregion
}
Most of the code here is self explanatory: you have attached property that bind to the element drag and drop events and handle them either through direct code or by delegating to the values set. There are some extension methods like ExecuteWhenLoaded and ExecuteWhenUnloaded which execute an action when the element has finished loading or when it is unloading. An important aspect here is that a window closing does not trigger the Unloaded event for its child elements, so you need to bind to the Dispatcher.StartedShutdown event as well:

/// <summary>
/// Execute an action when an element is unloaded
/// </summary>
/// <param name="element"></param>
/// <param name="action"></param>
public static void ExecuteWhenUnloaded(this UIElement element, Action action)
{
if (element == null)
{
throw new ArgumentNullException("element",
Resources.
UIExtensions_ExecuteWhenUnloaded_Element_cannot_be_null);
}
RoutedEventHandler elementOnUnloaded = null;
EventHandler dispatcherOnShutdownStarted = null;
// ReSharper disable AccessToModifiedClosure
elementOnUnloaded = (sender, args) =>
{
performExecution(element,
dispatcherOnShutdownStarted,
elementOnUnloaded,
action);
};
dispatcherOnShutdownStarted = (sender, args) =>
{
performExecution(element,
dispatcherOnShutdownStarted,
elementOnUnloaded, action);
};
// ReSharper restore AccessToModifiedClosure
FrameworkElement frameworkElement = element as FrameworkElement;
if (frameworkElement != null)
{
frameworkElement.Unloaded += elementOnUnloaded;
}
element.Dispatcher.ShutdownStarted += dispatcherOnShutdownStarted;
}

That is pretty much it for the drag and drop itself. You can implement IDropTarget on the ViewModel directly, but IDragSource needs to be binary serializable if you intend to drag and drop across application domains, so you usually implement it into a separate class that is a property of the dragged item view model or DataContext.

Because the DragService sets the status properties for each element, you can manipulate the appearance and behaviour of both drag source and drop target based on them. However, at this point the mouse will be the only indication that you are dragging something. You might want to actually drag something, especially since in a move operation the original element would be hidden during the drag. The problem here is that the drag source element cannot control the display of the dragged item in other applications, nor should it in its application, since it is not its responsibility. The solution: decorate an element over which you would drag something (like the root element of the entire window) with something that knows how to display dragged items:
Click to expand/collapse

/// <summary>
/// Decorator for an element that would respons visually to a drag-over operation
/// </summary>
public class DragAndDropAdornerDecorator : ContentControl
{
#region Instance fields

private DragAndDropAdorner mAdorner;

#endregion

#region Properties

/// <summary>
/// Visual content for the dragged data
/// </summary>
public FrameworkElement AdornerContent
{
get
{
return (FrameworkElement) GetValue(AdornerContentProperty);
}
set
{
SetValue(AdornerContentProperty, value);
}
}

/// <summary>
/// The data being dragged
/// </summary>
public object DraggedData
{
get
{
return GetValue(DraggedDataProperty);
}
set
{
SetValue(DraggedDataProperty, value);
}
}

/// <summary>
/// The position of the drag point in the decorator content
/// </summary>
public Point Offset
{
get
{
return (Point) GetValue(OffsetProperty);
}
set
{
SetValue(OffsetProperty, value);
}
}

/// <summary>
/// Represents the point in which a dragged item has first entered the drag zone.
/// Use it to create animations when a drop operation did not succeed.
/// </summary>
public Point? EntryPoint
{
get
{
return (Point?) GetValue(EntryPointProperty);
}
private set
{
SetValue(EntryPointPropertyKey, value);
}
}

#endregion

#region Constructors

/// <summary>
/// Initializes a new instance of the <see cref="DragAndDropAdornerDecorator"/> class.
/// </summary>
public DragAndDropAdornerDecorator()
{
Focusable = false; // By default don't want 'AdornedControl' to be focusable.

DataContextChanged += dragAndDropAdornerDecoratorDataContextChanged;
updateAdornerDataContext();
}

#endregion

#region Protected Methods

/// <summary>
/// Called when the <see cref="T:System.Windows.Media.VisualCollection"/> of the visual object is modified.
/// </summary>
/// <param name="visualAdded">The <see cref="T:System.Windows.Media.Visual"/> that was added to the collection</param><param name="visualRemoved">The <see cref="T:System.Windows.Media.Visual"/> that was removed from the collection</param>
protected override void OnVisualChildrenChanged(DependencyObject visualAdded,
DependencyObject visualRemoved)
{
UIElement element = visualRemoved as UIElement;
if (element != null)
{
dettachAdorner(element);
}
base.OnVisualChildrenChanged(visualAdded, visualRemoved);
element = visualAdded as UIElement;
if (element != null)
{
attachAdorner(element);
this.ExecuteWhenUnloaded(() => dettachAdorner(element));
}
}

#endregion

#region Private Methods

private void dragAndDropAdornerDecoratorDataContextChanged(object sender,
DependencyPropertyChangedEventArgs e)
{
updateAdornerDataContext();
}

/// <summary>
/// Update the DataContext of the adorner from the adorned control.
/// </summary>
private void updateAdornerDataContext()
{
if (AdornerContent != null)
{
AdornerContent.DataContext = DataContext;
}
}

private void attachAdorner(UIElement element)
{
mAdorner = new DragAndDropAdorner(element, AdornerContent)
{
Decorator = this
};
mAdorner.Attach();
AddLogicalChild(mAdorner.AdornerLayer);
element.AddHandler(DragEnterEvent, new DragEventHandler(elementDragEnter), true);
element.AddHandler(DragOverEvent, new DragEventHandler(elementDragOver), true);
element.AddHandler(DragLeaveEvent, new DragEventHandler(elementDragLeave), true);
element.AddHandler(QueryContinueDragEvent,
new QueryContinueDragEventHandler(elementQueryContinueDrag), true);
element.AddHandler(DropEvent,
new DragEventHandler(elementDrop), true);
hideAdorner();
}

private void elementDragEnter(object sender, DragEventArgs e)
{
EntryPoint = e.GetPosition(this);
}

private void elementDrop(object sender, DragEventArgs e)
{
hideAdorner();
}

private void elementQueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
if (!e.KeyStates.HasFlag(DragDropKeyStates.LeftMouseButton))
{
hideAdorner();
}
}

private void elementDragLeave(object sender, DragEventArgs e)
{
hideAdorner();
}

private void hideAdorner()
{
DraggedData = null;
EntryPoint = null;
if (mAdorner == null)
{
return;
}
mAdorner.Hide();
}

private void elementDragOver(object sender, DragEventArgs e)
{
DraggedData = DragService.GetBestDraggedDataObject(e);
showAdorner(e.GetPosition(this));
}

private void showAdorner(Point position)
{
if (mAdorner == null)
{
return;
}
mAdorner.Show(position);
}

private void dettachAdorner(UIElement element)
{
if (mAdorner == null)
{
return;
}
RemoveLogicalChild(mAdorner.AdornerLayer);
mAdorner.DisconnectChild();
mAdorner.Dettach();
mAdorner = null;
element.RemoveHandler(DragEnterEvent, new DragEventHandler(elementDragEnter));
element.RemoveHandler(DragOverEvent, new DragEventHandler(elementDragOver));
element.RemoveHandler(DragLeaveEvent, new DragEventHandler(elementDragLeave));
element.RemoveHandler(QueryContinueDragEvent,
new QueryContinueDragEventHandler(elementQueryContinueDrag));
element.RemoveHandler(DropEvent, new DragEventHandler(elementDrop));
}

#endregion

#region Static Instance fields

public static readonly DependencyProperty AdornerContentProperty
= DependencyProperty.Register("AdornerContent",
typeof (FrameworkElement),
typeof (DragAndDropAdornerDecorator),
new FrameworkPropertyMetadata(null));

public static readonly DependencyProperty DraggedDataProperty
= DependencyProperty.RegisterAttached(
"DraggedData",
typeof (object), typeof (DragAndDropAdornerDecorator),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.
OverridesInheritanceBehavior
| FrameworkPropertyMetadataOptions.Inherits)
);

public static readonly DependencyPropertyKey EntryPointPropertyKey
= DependencyProperty.RegisterReadOnly("EntryPoint",
typeof (Point?), typeof (DragAndDropAdornerDecorator),
new FrameworkPropertyMetadata(default(Point?)));

public static readonly DependencyProperty EntryPointProperty =
EntryPointPropertyKey.DependencyProperty;


public static readonly DependencyProperty OffsetProperty
= DependencyProperty.Register("Offset",
typeof (Point), typeof (DragAndDropAdornerDecorator),
new FrameworkPropertyMetadata(new Point()));

#endregion

#region Static Public Methods

///<summary>
/// Attached getter method for DraggedData
///</summary>
///<param name="element"></param>
///<returns></returns>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[AttachedPropertyBrowsableForType(typeof (UIElement))]
public static object GetDraggedData(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return element.GetValue(DraggedDataProperty);
}

///<summary>
/// Attached setter method for DraggedData
///</summary>
///<param name="element"></param>
///<param name="value"></param>
///<exception cref="ArgumentNullException"></exception>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public static void SetDraggedData(DependencyObject element, object value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(DraggedDataProperty, value);
}

#endregion
}
This code uses an adorner to display the dragged item over it. Nothing fancy, since the actual template for the dragged data is defined in the decorator as the content. This is not the place to discuss the adorner, though, so here is just the code:
Click to expand/collapse

/// <summary>
/// Adorner for the drag-and-drop operations: see DragHelper and DragAndDropDecorator
/// </summary>
public class DragAndDropAdorner : AdornerBase
{
#region Instance fields

private readonly FrameworkElement mChild;
private Point mPosition;

#endregion

#region Properties

/// <summary>
/// Gets the number of visual child elements within this element.
/// </summary>
/// <returns>
/// The number of visual child elements for this element.
/// </returns>
protected override int VisualChildrenCount
{
get
{
return 1;
}
}

/// <summary>
/// Gets an enumerator for logical child elements of this element.
/// </summary>
/// <returns>
/// An enumerator for logical child elements of this element.
/// </returns>
protected override IEnumerator LogicalChildren
{
get
{
yield return mChild;
}
}

/// <summary>
/// Reference to the decorator that instantiates the adorner
/// </summary>
public DragAndDropAdornerDecorator Decorator
{
get;
set;
}

#endregion

#region Constructors

/// <summary>
/// Instantiate an adorner for an element over which to show the dragged content
/// </summary>
/// <param name="adornedElement"></param>
/// <param name="adornerContent"></param>
public DragAndDropAdorner(UIElement adornedElement, FrameworkElement adornerContent)
: base(adornedElement)
{
IsHitTestVisible = false;
Focusable = false;
mChild = adornerContent;
connectChild();
}

#endregion

#region Public Methods

/// <summary>
/// Disconnect the child element from the visual tree so that it may be reused later.
/// </summary>
public void DisconnectChild()
{
RemoveLogicalChild(mChild);
RemoveVisualChild(mChild);
}

/// <summary>
/// Hide the adorner content
/// </summary>
public void Hide()
{
Opacity = 0.0;
Visibility = Visibility.Collapsed;
}

/// <summary>
/// Show the adorner content at a certain position
/// </summary>
/// <param name="point"></param>
public void Show(Point point)
{
mPosition = point;
Opacity = 1.0;
Visibility = Visibility.Visible;
InvalidateArrange();
}

#endregion

#region Protected Methods

/// <summary>
/// Implements any custom measuring behavior for the adorner.
/// </summary>
/// <returns>
/// A <see cref="T:System.Windows.Size"/> object representing the amount of layout space needed by the adorner.
/// </returns>
/// <param name="constraint">A size to constrain the adorner to.</param>
protected override Size MeasureOverride(Size constraint)
{
mChild.Measure(constraint);
return mChild.DesiredSize;
}

/// <summary>
/// When overridden in a derived class, positions child elements and determines a size for a <see cref="T:System.Windows.FrameworkElement"/> derived class.
/// </summary>
/// <returns>
/// The actual size used.
/// </returns>
/// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
protected override Size ArrangeOverride(Size finalSize)
{
double adornerWidth = mChild.DesiredSize.Width;
double adornerHeight = mChild.DesiredSize.Height;
double offsetX=0;
double offsetY=0;
if (Decorator!=null)
{
offsetX = -Decorator.Offset.X;
offsetY = -Decorator.Offset.Y;
}
mChild.Arrange(new Rect(mPosition.X + offsetX, mPosition.Y + offsetY, adornerWidth, adornerHeight));
return finalSize;
}

/// <summary>
/// Overrides <see cref="M:System.Windows.Media.Visual.GetVisualChild(System.Int32)"/>, and returns a child at the specified index from a collection of child elements.
/// </summary>
/// <returns>
/// The requested child element. This should not return null; if the provided index is out of range, an exception is thrown.
/// </returns>
/// <param name="index">The zero-based index of the requested child element in the collection.</param>
protected override Visual GetVisualChild(int index)
{
return mChild;
}

#endregion

#region Private Methods

private void connectChild()
{
AddLogicalChild(mChild);
AddVisualChild(mChild);
}

#endregion
}
You would only need to decorate a view and then define the AdornerContent property for the decorator and, optionally, the grab point offset for the dragged element.

All that is left here is to show some usage examples. Let's assume we need a View over which we can drag and drop items:
<UserControl x:Class="BestPractices.Views.SecondaryView"
[...]
UIUtils:DragService.DropTarget="{Binding .}"
UIUtils:DragService.BringIntoViewOnDrag="True"
UIUtils:DragService.ActivateOnDrag="True"
UIUtils:DragService.DragOverStatus="{Binding DragOverStatus,Mode=OneWayToSource}">
Here you have a user control view which has the drop target set to its own view model and it is set to update the DragOverStatus property of the ViewModel when its attached DragOverStatus property is changed. The status properties are inheritable, so all the children of the view have them set. It is easy to define a Button style that has its text bolded when a copy operation is allowed for a drop item:
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}" >  <Style.Triggers>
<DataTrigger Binding="{Binding DragOverStatus}" Value="{x:Static Utils:DragEffects.Copy}">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers
></Style>
Its content is more interesting:
<UIUtils:DragAndDropAdornerDecorator Offset="40,40">
<UIUtils:DragAndDropAdornerDecorator.AdornerContent>
<Controls:ContentItem
DataContext="{Binding Path=(UIUtils:DragAndDropAdornerDecorator.DraggedData),
RelativeSource={RelativeSource Self}}"

Opacity="0.7"/>
</UIUtils:DragAndDropAdornerDecorator.AdornerContent>
<DockPanel Background="{Binding Background,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
>
<Button Command="{m:CommandBinding AddItemCommand}"
DockPanel.Dock="Top"
>Add item</Button>
<Button Command="{m:CommandBinding RemoveItemCommand}"
DockPanel.Dock="Top"
>Remove item</Button>
<WrapPanel x:Name="ContainerPanel" >
</WrapPanel>
</DockPanel>
</UIUtils:DragAndDropAdornerDecorator>
The container for the items is a simple WrapPanel and it is placed in a dock panel together with add and remove item buttons. This dock panel is decorated as a drag visual container, and the content that is dragged is set to a custom control called ContentItem, with a drag point set to 40,40. The DataContext property of the item is set to the DraggedData property so that it expresses the actual dragged object.

Now we have set up a container to be a drop target for items. It displays the items as they are dragged over it. All we have left is to set up the items, the ContentItem control, to be a DragSource:

<Style TargetType="{x:Type Controls:ContentItem}">
<Setter Property="UIUtils:DragService.DragSource" Value="{Binding DragSource}"/>
<Setter Property="UIUtils:DragService.IsDragged" Value="{Binding IsDragged,Mode=OneWayToSource}"/>
<Setter Property="UIUtils:DragService.DragStatus" Value="{Binding DragStatus,Mode=OneWayToSource}"/>
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:ContentItem}">
<Border BorderThickness="1" BorderBrush="Blue" CornerRadius="2" Background="{TemplateBinding Background}" Width="75" Height="60">
<TextBlock Text="{Binding Id}" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontSize="22"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsDragged}" Value="True">
<Setter Property="Background" Value="LightPink"/>
</DataTrigger>
<DataTrigger Binding="{Binding DragStatus}" Value="{x:Static Utils:DragEffects.Copy}">
<Setter Property="Background" Value="Lime"/>
</DataTrigger>
</Style.Triggers>
</Style>
The control style defines as a drag source the DragSource property of the data context of the item and synchronizes with the data context the properties of IsDragged and DragStatus. Triggers then make is pinkish when dragged and greenish when it can be dropped. Notice that this applies to the original item, while its representation is dragged, so you have a feedback of what is going on with the item right at the source.

I won't put here the ViewModels or the data items, since they are pretty much part of the business context, not the drag and drop. Just return DragEffects. All on the effects methods and you can drag anything anywhere, for example.

That's it, folks: drag and drop completely MVVM, without as much as writing an event handler or caring about the actual elements in the viewmodel. It would be even easier if you would allow references to WPF assemblies in the ViewModels, since you could also get the source elements and do stuff with them, but that wouldn't be much of an MVVM pattern, would it?

And here is the AdornerBase class, just a simple helper class:

/// <summary>
/// Basic adorner class that exposes simple Attach and Dettach methods
/// </summary>
public abstract class AdornerBase : Adorner
{
#region Instance fields

private bool mIsDettached;

#endregion

#region Properties

public bool IsDettached
{
get
{
return mIsDettached;
}
}

public AdornerLayer AdornerLayer
{
get;
private set;
}

#endregion

#region Constructors

protected AdornerBase(UIElement adornedElement)
: base(adornedElement)
{
mIsDettached = true;
}

#endregion

#region Public Methods

/// <summary>
/// Attach the adorner to the element's adorner layer
/// </summary>
public void Attach()
{
AdornerLayer = AdornerLayer.GetAdornerLayer(AdornedElement);
if (AdornerLayer != null)
{
AdornerLayer.Add(this);
mIsDettached = false;
}
}

/// <summary>
/// Dettach the adorner from the element's adorner layer
/// </summary>
public void Dettach()
{
AdornerLayer = AdornerLayer ?? AdornerLayer.GetAdornerLayer(AdornedElement);
if (AdornerLayer != null)
{
AdornerLayer.Remove(this);
mIsDettached = true;
}
}

#endregion
}