NotificationStructureChanged - Houzkin/TreeStructures GitHub Wiki

Notification Content of ObservableTreeNode

Execute the following code:

public class ObservableNamedNode: ObservableGeneralTreeNode<ObservableNamedNode> {
    public string Name { get; set; }
    public override string ToString() {
        return this.Name;
    }
}

public static class SampleB {
    public static void Method() {
        Console.WriteLine("Building a collection as an N-ary tree.");

        var nodesDic = "ABCDEFGHI".ToCharArray().Select(x => x.ToString()).ToDictionary(x => x, x => new ObservableNamedNode() { Name = x });
        var root = nodesDic.Values.AssembleAsNAryTree(2);
        //
        Console.WriteLine(root.ToTreeDiagram(x => x.Name));

        EventHandler<StructureChangedEventArgs<ObservableNamedNode>> structreChangedHdlr = (s, e) => {
            Console.WriteLine($"sender:{s} \nTarget:{e.Target} TreeAction:{e.TreeAction} PreviousParentOfTarget:{e.PreviousParentOfTarget} OldIndex:{e.OldIndex} IsAncestorChanged:{e.IsAncestorChanged} IsDescendantChanged:{e.IsDescendantChanged}");
            if (e.IsAncestorChanged) {
                var info = e.AncestorInfo!;
                Console.WriteLine($"MovedTarget:{info.MovedTarget} OldIndex:{info.OldIndex} PreviousParentOfTarget:{info.PreviousParentOfTarget} IsRootChanged:{info.IsRootChanged}");
            } 
            if (e.IsDescendantChanged) {
                var info = e.DescendantInfo!;
                Console.WriteLine($"Target:{info.Target} SubtreeAction:{info.SubTreeAction} OldIndex:{info.OldIndex} PreviousParentOfTarget:{info.PreviousParentOfTarget}");
            }
            Console.Write("\n");
        };
        
        PropertyChangedEventHandler propertyChangedHdlr = (s, e) => { Console.WriteLine($"sender:{s} Parent Changed.\n"); };

        EventHandler disposedHdlr = (s, e) => { Console.WriteLine($"sender:{s} Disposed.\n"); };

        foreach (var node in root.Preorder()) {
            node.StructureChanged += structreChangedHdlr;
            node.PropertyChanged += propertyChangedHdlr;
            node.Disposed += disposedHdlr;
        }

        Console.WriteLine("Remove node D\n");
        nodesDic["B"].RemoveChild(nodesDic["D"]);
        Console.WriteLine(root.ToTreeDiagram(x => x.Name));

        Console.WriteLine("Add node D as a child node to node E.\n");
        nodesDic["E"].AddChild(nodesDic["D"]);
        Console.WriteLine(root.ToTreeDiagram(x => x.Name));

        Console.WriteLine("Move node E to be a child node of node C.\n");
        nodesDic["C"].AddChild(nodesDic["E"]);
        Console.WriteLine(root.ToTreeDiagram(x => x.Name));

        Console.WriteLine("Dispose node E \n");
        nodesDic["E"].Dispose();
        Console.WriteLine(root.ToTreeDiagram(x => x.Name));
    }
}

Explanation of Event Arguments

In addition to the information common to all nodes, if there are changes in ancestor nodes, IsAncestorChanged = true and AncestorInfo are stored.
If there are changes in descendant nodes, IsDescendantChanged = true and DescendantInfo are stored.

Notification on Deletion

screenshot 19 screenshot 21 screenshot 20

Nodes A and B, nodes C, E, F, G, nodes D, H, I have the same notification content.

Nodes A, B: IsDescendantChanged is true, and DescendantInfo is displayed.
Nodes C, E, F, G: Since they are not ancestors or descendants of the changed node D, both IsAncestorChanged and IsDescendantChanged are False.
Detached Nodes D, H, I: IsAncestorChanged is true, and AncestorInfo is displayed.

Notification on Addition

Next, add the previously deleted node D as a child node of node E.
screenshot 23

screenshot 22

Nodes A, B, E: Since there are changes in descendants, IsDescendantChanged is true,
Nodes C, F, G: Both are false,
Nodes D, H, I: Since there are changes in ancestors, IsAncestorChanged is true.

Notification on Movement

Move node E to be a child node of node C.
screenshot 25

screenshot 24

Viewing the entire tree (node A), node E moved within the tree, so TreeAction is Move.
Viewing from node B, it moved away from the SubTree, so SubTreeAction is Deviate.
Viewing from node C, it joined from outside the SubTree, so SubTreeAction is Join.

Since it is a movement within the tree, for nodes E, D, H, I, IsRootChanged is False.

⚠️ **GitHub.com Fallback** ⚠️