Control the dragged nodes in copy

Hi,
I have a group with items within it, that when dragged (in copy mode) I want it look different than its current look (more clean style, without its sub nodes).
In order to achieve this I’ve prepared a special template for it (a simple border), and I set it here in the PartManager:

public override Northwoods.GoXam.Model.ICopyDictionary CopyParts(IEnumerable coll, Northwoods.GoXam.Model.IDiagramModel destmodel)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> Northwoods.GoXam.Model.ICopyDictionary retVal = base.CopyParts(coll, destmodel);

<span =“Apple-tab-span” style=“white-space:pre”> foreach (TCanvasItemType canvasItem in retVal.Copies.Nodes)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> canvasItem.Category = NodeCategories.Dragged;
<span =“Apple-tab-span” style=“white-space:pre”> }
<span =“Apple-tab-span” style=“white-space:pre”> return retVal;
<span =“Apple-tab-span” style=“white-space:pre”> }

I have two problems:

  1. I can’t manage to get rid of the sub nodes (although the new template doesn’t include any element t hold child nodes).
  2. The mouse cursor location on the copied node looks like is calculated from the original group template, and not from the new one (I use Node.LocationSpot=“Center”) - it is far left from the dragged node.

Here is the “dragged” node template:

<Border x:Name="_nodeBorder" go:SpotPanel.Main="True" Style="{DynamicResource StandardNodeBorderStyle}"> Converter={x:Static CommonConverters:ImageConverters.BitmapToBitmapSourceConverter}}" Height="16" Width="16" Style="{DynamicResource CollapsableImage}"/> <TextBlock DockPanel.Dock="Left" x:Name="_itemName" Style="{DynamicResource TextBlockStyle}" HorizontalAlignment="Left" Text="{Binding Path=Data.DisplayName}" TextTrimming="CharacterEllipsis" />

Thanks in advance,
Or

Well, the normal behavior is that copying a Group also copies its subgraph – i.e. its member nodes and links.

Did you still want to copy those member nodes and links too?
I suppose you could use the same trick and use invisible or transparent DataTemplates for them too.

Or if you did not want to copy those member nodes and links, you could override your model’s AugmentCopyCollection method to be a no-op.

Regarding your second issue, the DraggingTool.CopiedParts property is a Dictionary<Part, DraggingTool.Info>.
You could find your Group in that dictionary and adjust the DraggingTool.Info.Point property.

Unfortunately, the internal DraggingTool method that generates that dictionary isn’t protected and virtual.
But the next thing the tool calls is MoveParts, which is virtual, so you could override that.
However you have to be careful to only adjust that information in the dictionary once, even though MoveParts gets called lots of times.

Caution: I haven’t tried this to make sure it works.

Thanks!
Overriding the model’s <span =“Apple-style-span” style=": rgb248, 248, 252; ">AugmentCopyCollection to be no-op did the trick, since all the copy/movement logic is done in a separated manager class.
Now I’m checking your suggestion for the second problem.

Another good news - I’ve implemented your suggestion:

public override void MoveParts(Dictionary<Part, DraggingTool.Info> parts, Point offset)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> base.MoveParts(parts, offset);

<span =“Apple-tab-span” style=“white-space:pre”> if (CopiedParts != null)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> if (!_isMoveStarted)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> foreach (KeyValuePair<Part, Info> copiedPart in CopiedParts)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> if (copiedPart.Key is Group)
<span =“Apple-tab-span” style=“white-space:pre”> {
<span =“Apple-tab-span” style=“white-space:pre”> copiedPart.Value.Point = new Point(Diagram.LastMousePointInModel.X,
<span =“Apple-tab-span” style=“white-space:pre”> Diagram.LastMousePointInModel.Y);
<span =“Apple-tab-span” style=“white-space:pre”> }
<span =“Apple-tab-span” style=“white-space:pre”> }
<span =“Apple-tab-span” style=“white-space:pre”> // This is a flag, since we only need to do this once
<span =“Apple-tab-span” style=“white-space:pre”> // since the drag was started, and this event keeps firing.
<span =“Apple-tab-span” style=“white-space:pre”> _isMoveStarted = true;
<span =“Apple-tab-span” style=“white-space:pre”> }
<span =“Apple-tab-span” style=“white-space:pre”> }
<span =“Apple-tab-span” style=“white-space:pre”> }
I’m clearing the _isMoveStarted flag in the DoStop() method.
It works perfectly fine, except of one case: when I’m dragging the node outside of the diagram and then return to it - then the mouse location is wrong like before. My guess is that I need to clear the flag again once the dragged item leaves the diagram - is there an event for that?

Thanks again for the solution.

I think the FrameworkElement.MouseLeave event will help.

<span =“Apple-style-span” style=": rgb248, 248, 252; “>Unfortunately the FrameworkElement.MouseLeave event doesn’t fire during the drag, only after the drop. Still looking for a solution, if you happen to think of something.
<span =“Apple-style-span” style=”: rgb248, 248, 252; ">Thanks

Are you using WPF? I’m sorry – I mistyped. I meant the DragLeave event.

That’s what we use. Our handler calls the DraggingTool.DoDragLeave method to remove the temporary copies created by a DragOver event. So you could override that. Do remember to call the base method!

<span =“Apple-style-span” style="font-family: ‘Times New Roman’; line-height: normal; font-size: medium; ">

The DraggingTool.DoDragLeave method is fired not only when dragging an item outside of the diagram, but also when dragging over certain elements, causing a bazaar behavior when I use the code above, still not sure why…

A DragLeave event happens any time during a drag-and-drop the mouse leaves an element. But while dragging the mouse there are a lot of elements that the mouse will normally cross over, so there are a lot of DragEnter and DragLeave events.