Drag-Drop onto a particular part

Hello,

I’d like to decide if the new node dragged is dropped onto an otherone.

If such, I want not only add the new node but also add a link between the new node and the node below, and finally deplace the new node location for readability.

But I don’t use the “group” node model.

All my node have the same type.

May i override some draggingtool functions or may i modify my PartManager.AddedNode overriding ?

I have soon override DraggingTool to decide to move all part’s node if “hidden”.

public class MyDragDropTool : DraggingTool
    {
        private void GetEffectiveCollection(List<Part> oPartList, Node oNode)
        {
            foreach (Link l in oNode.FindLinksOutOfPort("Out"))
            {
                Node n = l.GetOtherNode(oNode);
                if (n != null && n != oNode)
                {
                    oPartList.Add(n);
                    GetEffectiveCollection(oPartList, n);
                }
            }
        }

        public override Dictionary<Part, Info> ComputeEffectiveCollection(IEnumerable<Part> parts)
        {
            List<Part> MyPart = new List<Part>();
            foreach (Part oPart in parts)
            {
                MyPart.Add(oPart);
                if (oPart is Node)
                {
                    Node oNode = (Node)oPart;
                    MyNodeData oData = (MyNodeData)oNode.Data;
                    //if a SphPart is closed (not expanded) all the inside node should move with the part
                    if (oData != null && !oData.EverExpanded)
                    {
                        GetEffectiveCollection(MyPart, oNode);
                    }
                }
            }
            Dictionary<Part, Info> oCol = base.ComputeEffectiveCollection(MyPart);
            return oCol;
        }

Maybe, I make a mistake, should I use group ?
Aurore

Are you using the latest version 1.1 beta? If so, you might not need to customize the DraggingTool.

Just set the Part.DropOntoBehavior. For example, look at the new behavior in the OrgChartEditor sample. When the user drops a node over another node, a link is drawn from the stationary node to the dropped node. This is implemented by adding this attribute to the node’s DataTemplate:

    go:Part.DropOntoBehavior="AddsLinkFromNode"

No Groups needed.

Then, whether the dropped node is moved or not depends on what Diagram.Layout there is and under what conditions it performs layouts.

The default Layout only moves Nodes to give them a Location if they don’t already have one. But since the user’s dropping of a Node already assigns a Location for the new Node, it won’t move. So you’ll need to implement a Diagram.ExternalObjectsDropped event handler to shift the dropped Node(s), which are accessible via the Diagram.SelectedParts collection.

For the other kinds of Layout, the standard conditions will automatically cause a layout to be performed when adding a Node or a Link, so the dropped node(s) will be moved without any coding on your part.

I have the latest version (1.1.0.3), I see the above option. but I don’t understand.
When I run the sample, I can create new guy with double-click but when I drop a node over another one, nothing change.

The new guy stays with his link…

Aurore

No, the latest beta version is 1.1.1.

Hello,

I’m sorry to tell that, but I see in your code that some node may change to red background when it is possible to “droponto” another node.

Theoritically, it should work but I don’t arrive to use it…

When I drag-drop a new guy (created by double-click on another one) nothing change…

Maybe is it only possible with guy not yet link…

I see it works in planogram sample

Well, I will try in my code.

Aurore

PS : I forgot to tell that I’ve change the dll, i use now the 1.1.1.3 one.

PS2 : ok, It works fine with no linked node, is it a way to use this functionality to change links only with drops… ?

Hello,

I’m sorry but I don’t arrive to use “droponto” function.

<Style TargetType="go:SpotPanel"
           x:Key="SpotPanelStyle">        
        <Setter Property="go:Node.SelectionElementName" Value="oNodeBorder" />
        <Setter Property="go:Node.SelectionAdorned"  Value="True" />
        <Setter Property="go:Node.LocationSpot"  Value="Center" />
        <Setter Property="go:Node.Location"
                Value="{Binding Path=Data.Location, Mode=TwoWay}" />
        <Setter Property="go:Part.SelectionAdornmentTemplate"
                Value="{StaticResource SelectedTemplate}" />
    </Style>

<DataTemplate x:Key="QDPartTemplate">
            <go:SpotPanel Style="{StaticResource SpotPanelStyle}"
                          MouseEnter="Node_MouseEnter"
                          MouseLeave="Node_MouseLeave"
                          Name="oNodeBorder"
                          go:Part.SelectionAdornmentTemplate="{StaticResource SelectedTemplate}"
                          go:Part.DropOntoBehavior="AddsLinkFromNode"
                          Background="{Binding Path=Part.IsDropOntoAccepted,
                                   Converter={StaticResource convBoolBrush}}">
...
</DataTemplate>

 <DataTemplate x:Key="QDGroupTemplate">
            <go:SpotPanel Style="{StaticResource SpotPanelStyle}"
                          MouseEnter="Node_MouseEnter"
                          MouseLeave="Node_MouseLeave"
                              Name="oNodeBorder"
                              go:Part.SelectionAdornmentTemplate="{StaticResource SelectedTemplate}"
                          go:Part.DropOntoBehavior="AddsLinkFromNode"
                          Background="{Binding Path=Part.IsDropOntoAccepted,
                                   Converter={StaticResource convBoolBrush}}">
...
</DataTemplate>

<DataTemplate x:Key="QDVariableTemplate">
            <go:SpotPanel Style="{StaticResource SpotPanelStyle}"
                          MouseEnter="Node_MouseEnter"
                          MouseLeave="Node_MouseLeave"
                              Name="oNodeBorder"
                          >
...
</DataTemplate>

 <go:Diagram x:Name="myDiagram"                    
                    AllowDrop="True" AllowLink="True">
            <go:Diagram.DraggingTool>
                <go:DraggingTool DropOntoEnabled="True" />
            </go:Diagram.DraggingTool>

        </go:Diagram>

public class QD_GraphLinkModel : GraphLinksModel<QD_Node, String, String, QD_Link>
    {
        public QD_GraphLinkModel()
        {
            this.LinkCategoryPath = "Category";
            this.NodeKeyPath = "Key";
        }
}

public class QD_Node : GraphLinksModelNodeData<String>
    {
}

public class QD_Link : GraphLinksModelLinkData<String, String>
    {
}


private void LoadSurvey()
        {
            if (Links == null) Links = new ObservableCollection<QD_Link>();
            if (Nodes == null) Nodes = new ObservableCollection<QD_Node>();
            foreach (SphItem oItem in Session.Survey.Items)
            {
                Read(oItem, null);
            }

            if (QD_Model == null) QD_Model = new QD_GraphLinkModel();
            QD_Model.NodesSource = Nodes;
            QD_Model.LinksSource = Links;
            QD_Model.Modifiable = true;
        }

LoadSurvey is called in the OnLoaded event.

I don’t see where my error…

I want variable and group automatically adds onto part.
and variable can be added in groups also.

Thanks
Aurore

I don’t understand what you want.

It appears from your definitions that when the user drops a Node onto either a QDPart or a QDGroup, it will also create a new Link from that QDPart or QDGroup to that dropped Node. Was that your intent?

I can’t tell from your templates whether a QDGroup node is actually a Group node or not. Only Group nodes can have member Nodes and member Links. If it is a Group, then specifying go:Part.DropOntoBehavior=“AddsToGroup” will have the effect of adding dropped Nodes to the Group as new members.

I’m sorry if I’m not clear.

It’s exactly what I want. But It seems not to work. I don’t see where is my error.

My term QDGroup is not a GoXam group. It is the same type as QDPart.

Aurore

OK, no Northwoods.GoXam.Groups.

During the drag of a node over a QDPart or QDGroup node, does the Background of the stationary node change as you would expect?

Good morning,

no, the boolean stays false.

Thanks
Aurore

What do your Mouse_Enter and Mouse_Leave event handlers do? Does the DropOntoBehavior work without those two event handlers?

Are you trying both external drag-and-drops and internal ones?

Hello,

I copied your example to set visible the port only when mouse enter :

private void Node_MouseEnter(object sender, MouseEventArgs e)
        {
            SetPortsVisible(sender as UIElement, true);
        }
        private void SetPortsVisible(UIElement uielement, bool visible)
        {
            if (Part.FindAncestor<Palette>(uielement) == null)
            {
                SpotPanel sp = uielement as SpotPanel;
                if (sp == null) return;
                Node n = Part.FindAncestor<Node>(sp);
                if (n == null) return;
                n.Tag = visible;
            }
        }

        private void Node_MouseLeave(object sender, MouseEventArgs e)
        {
            SetPortsVisible(sender as UIElement, false);
        }

The DropOntoBehavior doesn’t work even without these event handlers.

I’ve trying the both drag-and-drop (from palette and from diagram node).

Aurore

Well, that’s puzzling. I wonder what else of importance might be different from the OrgChartEditor sample and our internal test cases.

Could you define a custom DraggingTool and look at the values of a couple of predicates during the drag?

public class CustomDraggingTool : DraggingTool { protected override bool ConsiderDragOver(Point pt, Part p) { bool result = base.ConsiderDragOver(pt, p); System.Diagnostics.Debug.WriteLine("ConsiderDragOver: " + result.ToString()); return result; } public override bool IsValidLink(Node fromnode, Node tonode, Link relink) { bool result = base.IsValidLink(fromnode, tonode, relink); System.Diagnostics.Debug.WriteLine("IsValidLink: " + result.ToString()); return result; } }
and install by replacing the Diagram.DraggingTool:

            
                
            
Maybe you can get a clue about what's going on this way. You'll probably need to improve the information that is displayed, and perhaps you'll want to set breakpoints here or on other methods to look at the arguments more carefully.

Ok, I try. but I can’t found IsValidLink with 3 parameters…
in base I have only base.IsValidLink(fromnode, tonode)

Thanks

the tests results :

ConsiderDragOver: False
ConsiderDragOver: False
ConsiderDragOver: False
ConsiderDragOver: False
ConsiderDragOver: False
ConsiderDragOver: False
IsValidLink: False
ConsiderDragOver: False
IsValidLink: False
ConsiderDragOver: False
IsValidLink: False

when I drag onto a vairable, only “ConsiderDragOver: False”.
When I drag onto a part :
“IsValidLink: False
ConsiderDragOver: False”

More precisely :

the point is (4,293)
the part bounds is x=0, y=236, width=101, height=101

well, the point should be part of bounds Northwoods.Part ? isn’t it ?

The problem comes from IsValidLink, if I return always true, it works as expected. Can you explain me what is done in “IsValidLink” ?

Thanks for your time.

Aurore

Please try the latest beta release, version 1.1.1.x.

I use soon the 1.1.1.3.

Have you a new one ?

Yes, we’ll be coming out with the release version of 1.1 soon.