views:

168

answers:

2

I'm using an adorner to show a 'ghost' of the element being dragged...

var adornerLayer = AdornerLayer.GetAdornerLayer(topLevelGrid);
dragAdorner = new DragAdorner(topLevelGrid, itemToDrag);
adornerLayer.Add(dragAdorner);
dragAdorner.UpdatePosition(e.GetPosition(topLevelGrid));

DragDrop.DoDragDrop(sourceItems, viewModel, DragDropEffects.Move);

adornerLayer.Remove(dragAdorner);
itemToDrag = null;

...but I can't find a nice way to update the position of the adorner during the drag. The closest I've got is by setting AllowDrop="true" on the top level grid and giving it a DragOver handler...

private void TopLevelGrid_OnDragOver(object sender, DragEventArgs e)
{
 dragAdorner.UpdatePosition(e.GetPosition(topLevelGrid));
}

But this means I don't get the proper DragDropEffects feedback on the cursor, i.e., it always shows the DragDropEffects.Move cursor instead of DragDropEffects.None until I'm over an actual drop target.

Does anyone know a better way to update the adorner position?

A: 

you should check out this blog post from Bea Stollnitz. It has a nice implementation of drag n drop with an adorner showing a "ghost image".

redoced
Thanks redoced. My code is similar to this...(I think some of the posts I was referring to when putting it together were themselves referring to this post), but looking closer at Bea Costa's code I was able to work out the differences that were causing my problem. I'll post my findings as another answer. Cheers.
IanR
A: 

So, looking closer at Bea's code that redoced was referring to...

I still set AllowDrop="true" on the top level grid and give it a DragOver handler where I can update the adorner position, but I also set the DragDropEffects to None here. Then I just need to add a DragOver handler to the actual drop target to also update the adorner position...and making sure to set e.Handled = true so that the top level grid's handler doesn't just set the effects back to None when I'm over a drop target...

private void TopLevelGrid_OnDragOver(object sender, DragEventArgs e)
{
 UpdateDragAdornerPosition(e.GetPosition(topLevelGrid));
 e.Effects = DragDropEffects.None;
 e.Handled = true;
}

private void DropTarget_OnDragOver(object sender, DragEventArgs e)
{
 UpdateDragAdornerPosition(e.GetPosition(topLevelGrid));
 e.Handled = true;
}
IanR