Ответ 1
Недавно я работал над своим собственным приложением, которое широко использует перетаскивание WPF и, проведя полдня (отладка, поиск в Интернете, перечитывая документацию) по той же самой проблеме, которую вы видите, я мог только заключить там "будущее совершенствование" похоронено где-то в библиотеке WPF.
Это было мое решение:
protected virtual void OnTargetDragLeave(object sender, DragEventArgs e)
{
_dragInProgress = false;
// It appears there a quirk in the drag/drop system. While the user is dragging the object
// over our control it appears the system will send us (quite frequently) DragLeave followed
// immediately by DragEnter events. So when we get DragLeave, we can't be sure that the
// drag/drop operation was actually terminated. Therefore, instead of doing cleanup
// immediately, we schedule the cleanup to execute later and if during that time we receive
// another DragEnter or DragOver event, then we don't do the cleanup.
_target.Dispatcher.BeginInvoke( new Action( ()=> {
if( _dragInProgress == false ) OnRealTargetDragLeave( sender, e ); } ) );
}
protected virtual void OnTargetDragOver(object sender, DragEventArgs e)
{
_dragInProgress = true;
OnQueryDragDataValid( sender, e );
}