Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Moving container remove children nodes (Read 9346 times)
Francisco Marquez
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 9
Joined: Jun 10th, 2014
Moving container remove children nodes
Sep 29th, 2014 at 7:17pm
Print Post  
Going ahead with the check of the WinRT, I noticed something odd. I was using the workarounds suggested by Stoyan on another post to have different layouts, and then I hit, what I think is a bug.

To reproduce all that is necessary is to have a container node, create some nodes and assign to the children collection of the container. I used the expand workaround that Stoyan suggested to simulate folding. Now, if we "fold" the container and unfold it, it works perfect, but if we fold it, then drag the container, then it seems that the Remove Child event is called for all the nodes in the container (!?). This is the call stack:


>      XP4.Windows.exe!XP4.Proto5.Proto5Page_Loaded.AnonymousMethod__1(object s, MindFusion.Diagramming.ContainerChildEventArgs args) Line 89      C#
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.DiagramBase.OnContainerChildRe
moved(MindFusion.Diagramming.ContainerChildEventArgs e)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.DiagramBase.c56aeb5d08ee0f4285
260831552871242(MindFusion.Diagramming.ContainerChildEventArgs c23fab9153505d12d724c605909b1666e)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.Diagram.c56aeb5d08ee0f42852608
31552871242(MindFusion.Diagramming.ContainerNode caea7e8555260f9623e8a44bb7fc28238, MindFusion.Diagramming.DiagramNode c2bd1975b77e201fdb68e0e40661032b1)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.ContainerNode.c1b0026136699094
af427420e65d8d9bc(MindFusion.Diagramming.DiagramItem c0f934f98b04a7a50f23ed22539c44464)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.ContainerNode.OnChildModified(
MindFusion.Diagramming.DiagramNode node, MindFusion.Diagramming.AdjustmentHandles handle)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.DiagramNode.EndDrag(MindFusion
.Diagramming.InteractionState ist)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.ContainerNode.EndDrag(MindFusi
on.Diagramming.InteractionState ist)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.InteractionState.Commit(Window
s.Foundation.Point currentPoint)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.BehaviorBase.OnMouseUp(Windows
.UI.Xaml.Input.PointerRoutedEventArgs e)      Unknown
     MindFusion.Diagramming.DLL!MindFusion.Diagramming.Diagram.c486a04520a30de215125b
32751a1dfb9(object c603582910ea0dec9eb2fce5d08ef5921, Windows.UI.Xaml.Input.PointerRoutedEventArgs c23fab9153505d12d724c605909b1666e)      Unknown

For reference, the code I use is very similar to the one suggested in this thread:

http://mindfusion.eu/Forum/YaBB.pl?num=1409768213

This is:

namespace XP4
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class Proto5 : Page
    {
        DiagramNodeCollection nodeColl = new DiagramNodeCollection();
        ContainerNode cont1;
        ContainerNode cont2;

        public Proto5()
        {
            this.InitializeComponent();
        }

        private void Proto5Page_Loaded(object sender, RoutedEventArgs e)
        {
            XP4Diagram.Behavior = Behavior.Modify;

            //Create container
            cont1 = XP4Diagram.Factory.CreateContainerNode(0, 0, 30, 30);
            cont1.Text = "Container 1";
            cont1.Brush = Brushes.LightGray;
            cont1.HandlesStyle = HandlesStyle.HatchHandles3;
            cont1.Expandable = true;
            cont1.ZBottom(false);

            // create child nodes for containers
            for (var i = 0; i < 5; i++)
            {
                var diagramNode = XP4Diagram.Factory.CreateShapeNode(0, 0, 30, 30);
                nodeColl.Add(diagramNode);
            }

            for (var i = 0; i < 5; i++)
            {
                cont1.Children.Add(nodeColl[i]);
            }
            
            ArrangeContainers();

            XP4Diagram.ExpandButtonAction = ExpandButtonAction.RaiseEvents;
            XP4Diagram.ExpandButtonClicked += (s, args) =>
            {
                var ctr = args.Node as ContainerNode;
                if (ctr != null)
                {
                    var items = GetContainerItems(ctr);
                    foreach (var item in items)
                        item.Visible = ctr.Expanded;

                    if (ctr.Expanded)
                    {
                        ctr.UpdateBounds(5);
                    }
                    else
                    {
                        var foldedRect = ctr.Bounds;
                        foldedRect.Height = ctr.CaptionHeight;
                        ctr.Bounds = foldedRect;
                    }
                }
            };

            XP4Diagram.ContainerChildRemoved += (s, args) =>
            {
                // Children removed!!!!
                var temp = args;
            };
        }

        void ArrangeContainers()
        {
            var innerLayout = new TreeLayout();
            innerLayout.NodeDistance /= 2;

            var outerLayout = new LayeredLayout();
            outerLayout.StraightenLongLinks = true;
            outerLayout.EnforceLinkFlow = true;
            outerLayout.NodeDistance /= 2;

            Arrange(XP4Diagram, outerLayout, innerLayout);
        }

        private void Arrange(Diagram diagram, Layout outerLayout, Layout innerLayout)
        {
            foreach (DiagramNode node in diagram.Nodes)
            {
                node.EnabledHandles = AdjustmentHandles.Move;
                node.AllowOutgoingLinks = false;
                ContainerNode container = node as ContainerNode;
                if (container == null)
                    continue;

                innerLayout.Arrange(diagram, GetContainerItems(container));
                container.UpdateBounds(5);
            }
            outerLayout.Arrange(diagram);
            diagram.ResizeToFitItems(5);
        }

        private DiagramItemCollection GetContainerItems(ContainerNode container)
        {
            DiagramItemCollection items = new DiagramItemCollection();
            foreach (DiagramNode node in container.Children)
            {
                items.Add(node);
            }
            return items;
        }

        private void backButton_Tapped(object sender, TappedRoutedEventArgs e)
        {
            if (Frame.CanGoBack) {
                Frame.GoBack();
            }
        }
    }

    static class ContainerExtensions
    {
        public static void UpdateBounds(this ContainerNode container, double margin)
        {
            if (container.Children.Count == 0)
                return;
            var r = container.Children[0].Bounds;
            foreach (DiagramNode node in container.Children)
                r.Union(node.Bounds);

            r.X -= margin;
            r.Y -= container.CaptionHeight + margin;
            r.Width += margin * 2;
            r.Height += container.CaptionHeight + margin * 2;

            container.SetBounds(r, false);
        }
    }

}


Can you let me know if this is indeed a bug?

Thanks!
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Moving container remove children nodes
Reply #1 - Oct 1st, 2014 at 11:24am
Print Post  
Try using this class as a work-around:

Code
Select All
public class MyContainerNode : ContainerNode
{
	protected override void OnChildModified(DiagramNode node, AdjustmentHandles handle)
	{
		if (!Expanded)
			return;

		// this will remove child nodes if they are outside container.Bounds
		// which happens for the simulated folded container
		base.OnChildModified(node, handle);
	}
} 



We should upload a beta version with built-in folding support in a few days.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Francisco Marquez
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 9
Joined: Jun 10th, 2014
Re: Moving container remove children nodes
Reply #2 - Oct 3rd, 2014 at 3:10pm
Print Post  
Thanks again Stoyan,

The workaround seems to be working, I'll have a look in detail in the coming days.

I look forward to the next beta!

Smiley
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Moving container remove children nodes
Reply #3 - Oct 10th, 2014 at 1:02pm
Print Post  
This build adds a Foldable property to ContainerNode:
https://mindfusion.eu/_beta/DiagramRT.1.1.1.zip

When enabled, the container shows a fold / unfold chevron image in the caption bar. Clicking it will fold the container to the caption bar's height. We'll improve the fold icon template and add some properties for customizing it for the official release.

If you prefer using the +/- expand icon from the custom implementation, you can continue folding and unfolding from ExpandButtonAction handler by simply setting container.Folded = !container.Folded;

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Francisco Marquez
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 9
Joined: Jun 10th, 2014
Re: Moving container remove children nodes
Reply #4 - Oct 11th, 2014 at 9:50am
Print Post  
Brilliant!! Downloading it as we speak, and will try it over the weekend.

Thanks again!
  
Back to top
 
IP Logged
 
Francisco Marquez
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 9
Joined: Jun 10th, 2014
Re: Moving container remove children nodes
Reply #5 - Oct 16th, 2014 at 6:22pm
Print Post  
I just wanted to thank you Stoyan, the beta you provided works great with the foldable property. So far I have not encountered any problem with it, although I keep on experimenting with hierarchies and different layouts, etc.

Thanks for your incredible support!
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint