title: WPF drag and drop on a button
body: <p>I'm writing a WPF application that has grids of buttons and I want to allow the user to drag and drop buttons between grids, possibly between different instances of the application. I've tried doing this by adding a handler to the PreviewMouseMove event on the button and then calling DoDragDrop if the left mouse button is down, but when I drag and drop the button it always ends up calling DoDragDrop twice and the drop event handler twice. Does anyone know why this happens and how to prevent it?</p>
  
  <p>Here's some example XAML which demonstrates the problem:</p>
  
  <pre><code>&lt;Window x:Class="WpfTest.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="MainWindow" Height="350" Width="525"&gt;
      &lt;DockPanel&gt;
          &lt;Button PreviewMouseMove="PreviewMouseMove" x:Name="m_button" Width="250"&gt;
              Hello, world!
          &lt;/Button&gt;
          &lt;Label Drop="Drop" AllowDrop="True"&gt;
              Drop here!
          &lt;/Label&gt;
      &lt;/DockPanel&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>and the corresponding code:</p>
  
  <pre><code>public partial class MainWindow : Window
  {
      public MainWindow()
      {
          InitializeComponent();
      }
  
      private void PreviewMouseMove(object sender, MouseEventArgs e)
      {
          if (e.LeftButton == MouseButtonState.Pressed)
          {
              ++m_dragIndex;
              System.Console.WriteLine("Dragged: " + m_dragIndex.ToString());
              DragDrop.DoDragDrop(m_button, m_dragIndex, DragDropEffects.All);
              e.Handled = true;
          }
      }
  
      private void Drop(object sender, DragEventArgs e)
      {
          System.Console.WriteLine("Dropped: " + e.Data.GetData(typeof(Int32)).ToString());
      }
  
      private int m_dragIndex;
  }
  </code></pre>
  
  <p>For a single drag, this gets written to the output:</p>
  
  <pre><code>Dragged: 1
  Dragged: 2
  Dropped: 2
  Dropped: 1
  </code></pre>
  
  <p><strong>UPDATE:</strong> I've changed the example code above to show which drop events get called when the button is dropped onto something.</p>
  
  <p><strong>UPDATE:</strong> Updated the question to include dragging between containers and application instances, since this is the motivating factor for using the DragDrop system.</p>