Well, it's not at all intuitive, but I think I've found a way to make it work:

Code:
public partial class Window1 : Window
{
        public Window1()
        {
            InitializeComponent();
            this.ellipse1.MouseDown += new MouseButtonEventHandler(ellipse1_MouseDown);
            this.ellipse1.QueryContinueDrag += new QueryContinueDragEventHandler(ellipse1_QueryContinueDrag);
        }

        void ellipse1_MouseDown(object sender, MouseEventArgs e)
        {
            DataObject data = new DataObject();
            DragDrop.DoDragDrop(
                this.ellipse1,
                data,
                DragDropEffects.All);
        }

        void ellipse1_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            if ((e.KeyStates & DragDropKeyStates.LeftMouseButton) != DragDropKeyStates.LeftMouseButton)
            {
                // This will happen at the end of the drag
            }
        }
}
You'll have to be careful to anticipate other things like mouse clicks (which would also trigger MouseDown), right-drags, and other such things. This is a lot less clean than the DragDrop event, but I guess it gets the job done.