I have some user controls that can drag/drop between a number of canvases. Some of the user controls also contain a number canvases that allows drag/drop action within the user control. I like the child elements that belongs to the canvases inside the user control to be able to drag/drop between canvases inside the user control, but not to the canvas that holds the user control (user control's parent canvas).
I tried to assign names to the Tag properties to identify the nest level of droppable canvases and attempt to allow/restrict the drop in the OnDropQuery event handler by something like:
private void OnDropQuery(object sender, DragDropQueryEventArgs e) { var destination = e.Options.Destination; if (e.Options.Status == DragStatus.DropDestinationQuery) { Canvas sourceCanvas = e.Options.Source.Parent as Canvas; if (sourceCanvas != null && destination.Tag == sourceCanvas.Tag) e.QueryResult = true; else e.QueryResult = false; e.Handled = true; } } The issue is e.Options.Source.Parent has become a ContentControl instead of the source canvas that holds the dragging item.
In my OnDragInfo handler, I have no problem getting the container canvas by the following:
private void OnDragInfo(object sender, DragDropEventArgs e) { FrameworkElement me = e.Options.Source as FrameworkElement; Canvas container = me.Parent as Canvas; if (container != null) { if (e.Options.Status == DragStatus.DragComplete) { // Only allow drag-drop within the same container container.Children.Remove(me); } } }I found out e.Options.Source.Parent sometimes change to ContentControl depending on e.Options.Status. For example, in OnDragQuery, I can use e.Options.Source.Parent to get the container canvas if e.Options.Status is DragQuery, but it becomes ContentControl if status is DropSourceQuery.
What is the proper way to get the source container of the dragging item? Is there a better way to implement my nested drag/drop situation without using the Tag trick?