private void HandleDragOver(object sender, JetListViewDragEventArgs e) { if (e.Data.GetDataPresent(typeof(JetListViewNode)) && e.DropTargetNode != null) { e.Effect = DragDropEffects.Move; e.DropTargetRenderMode = DropTargetRenderMode.InsertAny; // TODO: remove this test code /* * JetListViewNode dragNode = (JetListViewNode) e.Data.GetData( typeof(JetListViewNode ) ); * JetListViewNode dropNode = e.DropTargetNode; * JetListView list = (JetListView)sender; * Rectangle bounds = list.GetItemBounds( dropNode, list.Columns[0] ); // TODO: row bounds, not cell's * Point pnt = _propListView.PointToClient( new Point( e.X, e.Y ) ); * if((pnt.Y >= bounds.Top) && (pnt.Y < bounds.Bottom)) * e.DragInsert = ((pnt.Y - bounds.Top <= bounds.Height / 4) || (bounds.Bottom - pnt.Y < bounds.Height / 4)); * Trace.WriteLine(dropNode.ToString(), "DDR"); */ } else { e.Effect = DragDropEffects.None; } }
/// <summary> /// Handles the DnD <see cref="JetListView.DragOver"/> event from the underlying <see cref="JetListView"/>, and fires the own <see cref="ResourceDragOver"/> event for the external handlers (if none available, invokes the default handler). /// </summary> private void HandleDragOver(object sender, JetListViewDragEventArgs args) { try { IResource targetRes; if (!CheckDragDropMode(args, out targetRes)) { return; // Operation cancelled } // Call the outer handler for the drag-over operation if ((ResourceDragOver != null) && (args.Data.GetDataPresent(typeof(IResourceList)))) { // Call the custom handler IResourceList dragResources = (IResourceList)args.Data.GetData(typeof(IResourceList)); ResourceDragEventArgs resourceDragEventArgs = new ResourceDragEventArgs(targetRes, dragResources); ResourceDragOver(this, resourceDragEventArgs); args.Effect = resourceDragEventArgs.Effect; } else { // No custom handler defined, invoke the default handler if ((targetRes == RootResource) && (_rootResourceDropHandler != null)) // Empty/Root special handler { args.Effect = _rootResourceDropHandler.DragOver(targetRes, args.Data, args.AllowedEffect, args.KeyState); } else // Normal d'n'd handler { args.Effect = Core.UIManager.ProcessDragOver(targetRes, args.Data, args.AllowedEffect, args.KeyState, (args.Data.GetData(typeof(ResourceListView2)) == this)); } } } catch (Exception ex) { Core.ReportException(ex, ExceptionReportFlags.AttachLog); } }
private void HandleDragDrop(object sender, JetListViewDragEventArgs e) { if (e.Data.GetDataPresent(typeof(JetListViewNode))) { JetListViewNode dropTargetNode = e.DropTargetNode; JetListViewNode dragNode = (JetListViewNode)e.Data.GetData(typeof(JetListViewNode)); if (dropTargetNode != dragNode) { Rectangle rc = _propListView.GetItemBounds(dropTargetNode, _checkColumn); Point pnt = _propListView.PointToClient(new Point(e.X, e.Y)); if (pnt.Y < (rc.Top + rc.Bottom) / 2) { dropTargetNode = dropTargetNode.PrevNode; } _propListView.Nodes.Move(dragNode, dropTargetNode); } } }
/// <summary> /// Checks if the dragging mode could be switched to Insertion or not, and changes the droptarget to the parent node, if necessary, for the Insertion case. /// </summary> /// <param name="args"> /// <para>The original drag'n'drop event arguents coming from the list.</para> /// </param> /// <param name="resDropTarget">Returns the <see cref="IResource">resource</see> that is either dropped over, /// or a parent resource in case of the Insertion mode. /// <c>Null</c> for the top-level nodes when the root resource is not defined.</param> /// <returns>Whether the drag-drop operation is allowed (<c>True</c>) or not.</returns> protected bool CheckDragDropMode(JetListViewDragEventArgs args, out IResource resDropTarget) { // Dragging within the same control? bool sameView = args.Data.GetData(typeof(ResourceListView2)) == this; // Prohibit dragging items within the same control if ((!AllowSameViewDrag) && (sameView)) { args.DropTargetRenderMode = DropTargetRenderMode.Restricted; args.Effect = DragDropEffects.None; resDropTarget = null; return(false); // Prohibit } // Assume the target won't change JetListViewNode nodeDropTarget = args.DropTargetNode; // Check for special processing for the Insertion mode if (args.DropTargetNode != null) { // Over some item if (sameView) { // Same view drag, check for possible insertion if ((args.DropTargetRenderMode & DropTargetRenderMode.InsertAny) != 0) // If it's set to Insert by the list, then reordering is allowed { // In the insertion mode, the drop action applies to the parent of the node over which the cursor is located if (args.DropTargetNode.Parent != null) // Reordering in the tree — switch to parent { nodeDropTarget = args.DropTargetNode.Parent; } else // Dragging not in a tree but in a plain list; such scenario is not yet supported { args.DropTargetRenderMode = DropTargetRenderMode.Over; } } } else // Not same view, no insertion allowed { args.DropTargetRenderMode = DropTargetRenderMode.Over; } } else // Over empty space { args.DropTargetRenderMode = DropTargetRenderMode.Over; } // Get the target resource and ensure it's OK object dataDropTarget = ((nodeDropTarget == null) || (nodeDropTarget.Data == null)) ? _resRoot : nodeDropTarget.Data; resDropTarget = dataDropTarget as IResource; if ((resDropTarget == null) != (dataDropTarget == null)) // If the data type is not IResource { throw new InvalidOperationException(String.Format("Invalid data type attached to a resource list/tree view node.")); } // If the drop is over the empty space, and the empty-drop-resource (Root) has not been defined if (resDropTarget == null) { args.DropTargetRenderMode = DropTargetRenderMode.Restricted; args.Effect = DragDropEffects.None; resDropTarget = null; return(false); // Prohibit } return(true); // Allow }
/// <summary> /// Handles the DnD <see cref="JetListView.DragDrop"/> event from the underlying <see cref="JetListView"/>, and fires the own <see cref="ResourceDrop"/> event for the external handlers (if none available, invokes the default handler). /// </summary> private void HandleDragDrop(object sender, JetListViewDragEventArgs args) { try { //////////// // Prepare JetListViewNode nodeInsertionPoint = args.DropTargetNode; // In tree-insertion-mode, we drop to the parent, and here we store the original target to use as an insertion point IResource targetRes; if (!CheckDragDropMode(args, out targetRes)) { return; // Operation cancelled } // The resources being dragged IResourceList resDragged = args.Data.GetDataPresent(typeof(IResourceList)) ? (IResourceList)args.Data.GetData(typeof(IResourceList)) : Core.ResourceStore.EmptyResourceList; lock (resDragged) // Kill the resource list to avoid the changes resDragged = Core.ResourceStore.ListFromIds(resDragged.ResourceIds, false); //////////// // Reorder // If we were dragging in the insertion mode, change the order // Do it beforehand to avoid “jumping” the item when it first gets added to the end and then jumps to the proper place if (((args.DropTargetRenderMode & DropTargetRenderMode.InsertAny) != 0) && (nodeInsertionPoint != null)) { if (nodeInsertionPoint.Parent != null) { // Collect IDs of the current set of resources under the node (they may be useful if there's no existing order yet) // TODO: lock? IntArrayList arOld = new IntArrayList(nodeInsertionPoint.Parent.Nodes.Count); foreach (JetListViewNode node in nodeInsertionPoint.Parent.Nodes) { arOld.Add(((IResource)node.Data).OriginalId); } UserResourceOrder uro = new UserResourceOrder( nodeInsertionPoint.Parent.Data != null ? (IResource)nodeInsertionPoint.Parent.Data : _resRoot , JobPriority.Immediate); uro.Insert( ((IResource)nodeInsertionPoint.Data).OriginalId , resDragged.ResourceIds , ((args.DropTargetRenderMode & DropTargetRenderMode.InsertBelow) != 0) , arOld); } } ///////// // Drop // Invoke the external handler for the drop event if ((ResourceDrop != null) && (resDragged.Count > 0)) // A custom handler is available { ResourceDrop(this, new ResourceDragEventArgs(targetRes, resDragged)); } else { // No custom handler, invoke the default one if ((targetRes == RootResource) && (_rootResourceDropHandler != null)) // Empty/Root special handler { _rootResourceDropHandler.Drop(targetRes, args.Data, args.AllowedEffect, args.KeyState); } else // Normal d'n'd handler { Core.UIManager.ProcessDragDrop(targetRes, args.Data, args.AllowedEffect, args.KeyState); } } } catch (Exception ex) { Core.ReportException(ex, ExceptionReportFlags.AttachLog); } }