I've implemented a little WPF app to drag an animal from the shop in to my barn. ;-)
I'm using:
- MVVMlight and its
EventToCommand
behaviors - The animal is a simple
Border
listening onMouseDown
- The barn is an
ItemsControl
bound to anObservableCollection
of the ViewModel. It listens to 3 events:DragEnter
(adds a dummy animal into theObservableCollection
to preview where the animal is placed in the barn)DragLeave
(removes the dummy animal if the animal isn't dropped)Drop
(sets the animal to the designated place in the barn).
Sorry. I don't have the reputation to upload images. So I try some ascii arts (try to image dragging the donkey into the barn):
Shop | Barn
-------------------------
Mouse | [Mouse] [Dog]
Cat | [.]
Dog | ^
Donkey-|--|
Here's the problem:
If I drag an animal into the barn onto it's designated space (the preview dummy):
DragLeave
removes the dummy item and immediately theDragEnter
will be fired to redraw the dummy item. Goto step 1.
An inifite loop. The flickering is up and running!
Does anyone know a nice little workaround?
So here's the code of my ViewModel:
private string _dummy;
public ObservableCollection<string> Animals { get; private set; }
private void StartDrag(FrameworkElement element)
{
var animal = element.DataContext as string;
if (animal == null) return;
System.Windows.DragDrop.DoDragDrop(element, animal, DragDropEffects.Copy);
}
private void PreviewDrop(DragEventArgs args)
{
if (args.Data.GetDataPresent(typeof (string)))
AddDummy();
}
private void StopDrop(DragEventArgs args)
{
RemoveDummy();
}
private void Drop(DragEventArgs args)
{
var animal = args.Data.GetData(typeof (string)) as string;
if (animal == null) return;
RemoveDummy();
Animals.Add(animal);
}
private void RemoveDummy()
{
if (_dummy == null) return;
Animals.Remove(_dummy);
_dummy = null;
}
private void AddDummy()
{
if (_dummy != null) return;
_dummy = ".";
Animals.Add(_dummy);
}
Thanks for your help
Marcel