The MindFusion Forums
Flow Diagramming Components >> WPF >> move selected node using arrow keys
https://mindfusion.eu/Forum/YaBB.pl?num=1491891857

Message started by kelum on Apr 11th, 2017 at 6:24am

Title: move selected node using arrow keys
Post by kelum on Apr 11th, 2017 at 6:24am
How to move selected node using Arrow keys ?

Arrow.Left
Arrow.Right
Arrow.Up
Arrow.Down


Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 11th, 2017 at 8:25am
See http://mindfusion.eu/Forum/YaBB.pl?num=1337156437/1#1

Title: Re: move selected node using arrow keys
Post by kelum on Apr 12th, 2017 at 3:06am
I added following command binding in constructor

[code]diagram.CommandBindings.Add(new CommandBinding(Diagram.NavigateLeft,
                (sender, args) =>
                { DiagramNode node = diagram.ActiveItem as DiagramNode;
                    if (node != null)
                    {
                        node.Move(node.Bounds.Left - 10, node.Bounds.Top);
                    }
                  
                }));[/code]

once I added that and put item on to canvas I can move item to left side using Arrow.Left Key , other keys not working here.

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 12th, 2017 at 8:52am
There are also NavigateRight, NavigateUp, NavigateDown commands - override them the same way and call node.Move with appropriate coordinates.

Title: Re: move selected node using arrow keys
Post by kelum on Apr 17th, 2017 at 1:10pm
okay now that working fine, but there is small issue , once I select an item, an move it. I can move it over(out of) the defined canvas, I want to restrict that , how can I do that

here the pic of it

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 17th, 2017 at 1:35pm
Compare new coordinates against diagram.Bounds before assigning them to the node, making sure the new values falls within the diagram.Bounds range, e.g.

[code]
// left arrow handler
if (node.Bounds.Left - 10 >= diagram.Bounds.Left)
    node.Move(node.Bounds.Left - 10, node.Bounds.Top);[/code]

Regards,
Slavcho

Title: Re: move selected node using arrow keys
Post by kelum on Apr 17th, 2017 at 3:05pm
as you guided, for all arrow key operations

I composed following code,

but only the  "left arrow handler" working  here

[code]
            // left arrow handler
            diagram.CommandBindings.Add(
            new CommandBinding(Diagram.NavigateLeft, (sender, args) =>
            {
            DiagramNode node = diagram.ActiveItem as DiagramNode;            
            if (node.Bounds.Left - 10 >= diagram.Bounds.Left)
                node.Move(node.Bounds.Left - 10, node.Bounds.Top);

            }));

            // right arrow handler
            diagram.CommandBindings.Add(
            new CommandBinding(Diagram.NavigateRight, (sender, args) =>
            {
                DiagramNode node = diagram.ActiveItem as DiagramNode;
                if (node.Bounds.Right - 10 >= diagram.Bounds.Right)
                    node.Move(node.Bounds.Right - 10, node.Bounds.Top);
            }));

            // up arrow handler
            diagram.CommandBindings.Add(
            new CommandBinding(Diagram.NavigateUp, (sender, args) =>
            {
                DiagramNode node = diagram.ActiveItem as DiagramNode;
                if (node.Bounds.Top - 10 >= diagram.Bounds.Top)
                    node.Move(node.Bounds.Top - 10, node.Bounds.Top);
            }));

            // down arrow handler
            diagram.CommandBindings.Add(
            new CommandBinding(Diagram.NavigateDown, (sender, args) =>
            {
                DiagramNode node = diagram.ActiveItem as DiagramNode;
                if (node.Bounds.Bottom - 10 >= diagram.Bounds.Bottom)
                    node.Move(node.Bounds.Bottom - 10, node.Bounds.Bottom);
            }));
[/code]

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 17th, 2017 at 3:26pm
In right and bottom cases you should compare with <= operator, otherwise the if condition is always false when a node is originally inside the diagram.

Title: Re: move selected node using arrow keys
Post by kelum on Apr 17th, 2017 at 3:35pm
up arrow key function and down arrow key functions still not working properly

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 18th, 2017 at 12:19pm
You should pass new Top values as Y argument of Move, your code shows them as Xes. This is the correct code -

[code]
// left arrow handler
diagram.CommandBindings.Add(
     new CommandBinding(Diagram.NavigateLeft, (sender, args) =>
     {
           var node = diagram.ActiveItem as DiagramNode;
           if (node != null && node.Bounds.Left - 10 >= diagram.Bounds.Left)
                 node.Move(node.Bounds.Left - 10, node.Bounds.Top);

     }));

// right arrow handler
diagram.CommandBindings.Add(
     new CommandBinding(Diagram.NavigateRight, (sender, args) =>
     {
           var node = diagram.ActiveItem as DiagramNode;
           if (node != null && node.Bounds.Right + 10 <= diagram.Bounds.Right)
                 node.Move(node.Bounds.Left + 10, node.Bounds.Top);
     }));

// up arrow handler
diagram.CommandBindings.Add(
     new CommandBinding(Diagram.NavigateUp, (sender, args) =>
     {
           var node = diagram.ActiveItem as DiagramNode;
           if (node != null && node.Bounds.Top - 10 >= diagram.Bounds.Top)
                 node.Move(node.Bounds.Left, node.Bounds.Top - 10);
     }));

// down arrow handler
diagram.CommandBindings.Add(
     new CommandBinding(Diagram.NavigateDown, (sender, args) =>
     {
           var node = diagram.ActiveItem as DiagramNode;
           if (node != null && node.Bounds.Bottom + 10 <= diagram.Bounds.Bottom)
                 node.Move(node.Bounds.Left, node.Bounds.Top + 10);
     }));[/code]

Title: Re: move selected node using arrow keys
Post by kelum on Apr 19th, 2017 at 3:27am
now this is working for individual items, once I group few nodes and try to move using arrow keys , I want to move those all elements as a group, but currently its moving only last selected item, how can I resolve this ?

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 19th, 2017 at 8:31am
Do the same for each node in diagram.Selection.Nodes instead of diagram.ActiveItem.

Title: Re: move selected node using arrow keys
Post by kelum on Apr 19th, 2017 at 9:21am
As you said I changed following code


Code (]var node = diagram.ActiveItem as DiagramNode;[/code):


To

[code] var node = diagram.Selection.Nodes as DiagramNodeCollection;;


but then having following error

Cannot convert type 'DiagramNodeCollection' does not contain a definition for 'Bounds' and no extension method 'Bounds' accepting a first argument of type 'DiagramNodeCollection'

'DiagramNodeCollection' does not contain a definition for 'Move' and no extension method 'Move' accepting a first argument of type 'DiagramNodeCollection' could be found

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 19th, 2017 at 11:26am
Selection.Nodes is a collection that contains the selected nodes, you'll need to loop over it -

[code]
foreach (var node in diagram.Selection.Nodes)
  node.Move....[/code]

Title: Re: move selected node using arrow keys
Post by kelum on Apr 19th, 2017 at 4:57pm
thanks for the continues support, I have another problem related to this scenario,

Once moving Nodes using arrow keys, I want to restrict overlap scenarios also

these are the steps for that scenario

1. select a Node
2. move that using arrow key,    
     if
       its overlapping with existing node, revoke that move at reset to previous location.

    else
          allow to move that node

Thnks
Kelum

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 20th, 2017 at 10:11am
Modify the FindOverlaps method to take bounds argument -


Code (]
List<DiagramNode> FindOverlaps(
     DiagramNode modifiedNode, Rect bounds, double minDist)
{
     bounds.Inflate(minDist - 1, minDist - 1);

     var overlaps = new List<DiagramNode>();
     ....[/code):



Older places where you call it such as OnNodeModifying, also pass node.Bounds like FindOverlaps(e.Node, e.Node.Bounds, 5). In arrow-key movements methods add an if statement that checks whether new rect leads to overlaps before assigning it -

[code]
var rect = node.Bounds;
rect.X = rect.Left - 10;
if (FindOverlaps(node, rect, 5).Count == 0)
    node.Move(node.Bounds.Left - 10, node.Bounds.Top);

Title: Re: move selected node using arrow keys
Post by kelum on Apr 20th, 2017 at 5:47pm
so as you mentioned I changed code


Code (]        List<DiagramNode> FindOverlaps(DiagramNode modifiedNode, Rect bounds, double minDist)
        {
            
            bounds.Inflate(minDist - 1, minDist - 1);

            var overlaps = new List<DiagramNode>();
            foreach (var node in flowchart.Nodes)
            {
                if (modifiedNode == node)
                    continue;
                if (bounds.IntersectsWith(node.Bounds))
                    overlaps.Add(node);
            }
            return overlaps;
        }[/code):



and all the arrow key operations changed as follows

[code]            // left arrow handler
            flowchart.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateLeft, (sender, args) =>
                {
                    foreach (var node in flowchart.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left - 10;

                        if (node != null && node.Bounds.Left - 10 >= flowchart.Bounds.Left && (FindOverlaps(node, rect, 5).Count == 0))
                        {
                            node.Move(node.Bounds.Left - 10, node.Bounds.Top);
                        }

                    }
                }));

            // right arrow handler
            flowchart.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateRight, (sender, args) =>
                {                  
                    foreach (var node in flowchart.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left - 10;

                        if (node != null && node.Bounds.Right + 10 <= flowchart.Bounds.Right && (FindOverlaps(node, rect, 5).Count == 0))
                        {
                            node.Move(node.Bounds.Left + 10, node.Bounds.Top);
                        }
                    }
                }));

            // up arrow handler
            flowchart.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateUp, (sender, args) =>
                {
                    foreach (var node in flowchart.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left - 10;

                        if (node != null && node.Bounds.Top - 10 >= flowchart.Bounds.Top && (FindOverlaps(node, rect, 5).Count == 0))
                        {
                            node.Move(node.Bounds.Left, node.Bounds.Top - 10);
                        }
                    }


                }));

            // down arrow handler
            flowchart.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateDown, (sender, args) =>
                {
                    foreach (var node in flowchart.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left - 10;

                        if (node != null && node.Bounds.Bottom + 10 <= flowchart.Bounds.Bottom && (FindOverlaps(node, rect, 5).Count == 0))
                        {
                            node.Move(node.Bounds.Left, node.Bounds.Top + 10);
                        }
                    }
                }));


this is compiling without errors, but in here once move one node over other node (overlap) then its locking each other, by selecting one of that overlapped node I can't move node away using arrow keys

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 21st, 2017 at 5:40am
rect.X = rect.Left - 10 is only valid when you move to the left, you'll need to alter this expression for other directions.

If you allow nodes to overlap at any point, than offsetting by just 10 pixels might not find a non-overlapping position so it won't accept the movement. You might want to change the logic so that it always accepts movement if the moved node currently overlaps with another one.

Title: Re: move selected node using arrow keys
Post by kelum on Apr 21st, 2017 at 9:04am
so as you mentioned I'updated code,

then Left Arrow Key and Up Arrow Key started to working properly (which is i can close up to 5 pixels, then those are not overlap)


Code (]            // left arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateLeft, (sender, args) =>
                {                   
                    foreach (var node in diagram.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left - 10;

                        if (node != null && node.Bounds.Left - 10 >= diagram.Bounds.Left && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left - 10, node.Bounds.Top);
                        }

                    }
                }));
                       
              // up arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateUp, (sender, args) =>
                {                  

                    foreach (var node in diagram.Selection.Nodes)
                    {

                        var rect = node.Bounds;
                        rect.Y = rect.Top - 10;

                        if (node != null && node.Bounds.Top - 10 >= diagram.Bounds.Top && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left, node.Bounds.Top - 10);
                        }
                    }


                }));[/code):



Left Arrow Key Operation with proper distance


Up Arrow Key Operation with proper distance


but Right arrow key and Bottom Arrow key not working like Left Arrow Key and Up Arrow Key , which is can't close up to 5 pixels they are locating with different spaces
[code]
            // right arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateRight, (sender, args) =>
                {
                  
                    foreach (var node in diagram.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Right + 10;

                        if (node != null && node.Bounds.Right + 10 <= diagram.Bounds.Right && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left + 10, node.Bounds.Top);
                        }
                    }
                }));



            // down arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateDown, (sender, args) =>
                {
                   
                    foreach (var node in diagram.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.Y = rect.Bottom + 10;

                        if (node != null && node.Bounds.Bottom + 10 <= diagram.Bounds.Bottom && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left, node.Bounds.Top + 10);
                        }
                    }
                }));


Bottom Arrow Key Operation with wide distance


http://i.imgur.com/DHpOZrT.png

Right Arrow Key Operation with wide distance


http://i.imgur.com/3xHpqwT.png

How can I reduce more spaces in right and down arrow handlers like up and left handlers

Title: Re: move selected node using arrow keys
Post by kelum on Apr 21st, 2017 at 9:17am
Anyway I found the solution like this,


[code]            // left arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateLeft, (sender, args) =>
                {                   
                    foreach (var node in diagram.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left - 10;

                        if (node != null && node.Bounds.Left - 10 >= diagram.Bounds.Left && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left - 10, node.Bounds.Top);
                        }

                    }
                }));



            // up arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateUp, (sender, args) =>
                {                  

                    foreach (var node in diagram.Selection.Nodes)
                    {

                        var rect = node.Bounds;
                        rect.Y = rect.Top - 10;

                        if (node != null && node.Bounds.Top - 10 >= diagram.Bounds.Top && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left, node.Bounds.Top - 10);
                        }
                    }


                }));
                       
               // right arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateRight, (sender, args) =>
                {
                  
                    foreach (var node in diagram.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.X = rect.Left + 10;

                        if (node != null && node.Bounds.Right + 10 <= diagram.Bounds.Right && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left + 10, node.Bounds.Top);
                        }
                    }
                }));

            // down arrow handler
            diagram.CommandBindings.Add(
                new CommandBinding(Diagram.NavigateDown, (sender, args) =>
                {
                   
                    foreach (var node in diagram.Selection.Nodes)
                    {
                        var rect = node.Bounds;
                        rect.Y = rect.Top + 10;

                        if (node != null && node.Bounds.Bottom + 10 <= diagram.Bounds.Bottom && (FindOverlaps(node, rect, 2).Count == 0))
                        {
                            node.Move(node.Bounds.Left, node.Bounds.Top + 10);
                        }
                    }
                }));[/code]

let me know if you have suggestion

Title: Re: move selected node using arrow keys
Post by Slavcho on Apr 21st, 2017 at 10:05am
It should look like this as you've found, otherwise it didn't match the positions where you are moving the node on next line -

// right
rect.X = rect.Left + 10;

// down
rect.Y = rect.Top + 10;

The MindFusion Forums » Powered by YaBB 2.6.11!
YaBB Forum Software © 2000-2024. All Rights Reserved.