While working on an application that requires drag and drop, I ran into trouble when trying to figure out where in the target list (in my case, a ListBox) to insert the dropped item. I ran across Josh Smith’s article Drag and Drop Items in a WPF ListView which covers (quite nicely) how to handle drag and drop operations within and between ListViews. While reading through the code, I found that he uses some code from Dan Crevier which was posted on Lester’s Blog. Ok, now that I have taken you through the tangled web of other people’s code, I will share how I used the code and changed it a little to work in my situation.
public static Point GetMousePosition(Visual relativeTo) { Win32Point mouse = new Win32Point(); GetCursorPos(ref mouse); System.Windows.Interop.HwndSource presentationSource = (System.Windows.Interop.HwndSource)PresentationSource.FromVisual(relativeTo); ScreenToClient(presentationSource.Handle, ref mouse); GeneralTransform transform = relativeTo.TransformToAncestor(presentationSource.RootVisual); Point offset = transform.Transform(new Point(0, 0)); return new Point(mouse.X - offset.X, mouse.Y - offset.Y); } public static int GetIndexUnderDragCursor(ItemsControl control) { int index = -1; for (int i = 0; i < control.Items.Count; ++i) { if (control.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated) { DependencyObject item = control.ItemContainerGenerator.ContainerFromIndex(i); if (IsMouseOver(item as Visual)) { index = i; break; } } } return index; } public static bool IsMouseOver(Visual target) { if (target == null) return false; Rect bounds = VisualTreeHelper.GetDescendantBounds(target); Point mousePos = GetMousePosition(target); return bounds.Contains(mousePos); }
I didn’t change the GetMousePosition method at all from what I found on Lester’s blog. Then I slightly modified some of Josh’s code so that it is a little more general. I hope this helps. Suggestions welcome.
You might want to consider using the modified version of Dan Crevier’s GetMousePosition method, as seen in my article. If you are running an app on a machine whose monitor has better resolution than the standard 96 dpi, you’ll encounter problems with Crevier’s implementation. His code doesn’t take into account the fact that WPF works with logical pixels.
Josh
Thanks Josh. I’ll check it out.
very nice topic thnkss