コード例 #1
0
        private void DeleteBtnClick(object sender, EventArgs e)
        {
            ListBox listbox = GetActiveList();
            DomNode item    = listbox != null?Adapters.As <DomNode>(listbox.SelectedItem) : null;

            if (item != null)
            {
                GameContext.As <ITransactionContext>().DoTransaction(() =>
                {
                    item.RemoveFromParent();
                }, "Delete terrain map");
                m_propertyGrid.Bind(null);
            }
        }
コード例 #2
0
ファイル: TestDomNode.cs プロジェクト: truongascii/ATF
        public void TestRemoveFromParentList()
        {
            DomNodeType type      = new DomNodeType("type");
            ChildInfo   childInfo = new ChildInfo("child", type, true);

            type.Define(childInfo);
            DomNode parent = new DomNode(type);
            DomNode child  = new DomNode(type);

            parent.GetChildList(childInfo).Add(child);
            child.RemoveFromParent();
            CollectionAssert.IsEmpty(parent.Children);
            Assert.Null(child.Parent);
        }
コード例 #3
0
        protected virtual bool RemoveProperty()
        {
            ITransactionContext transactionContext = EditingContext.Cast <ITransactionContext>();
            bool success = transactionContext.DoTransaction(delegate
            {
                foreach (ScriptNode module in EditingContext.Items.AsIEnumerable <ScriptNode>())
                {
                    DomNode node = GetDynamicDomNode(module);
                    node.RemoveFromParent();
                }
            }, string.Format("Remove: {0}".Localize(), Descriptor.Category + '/' + Descriptor.DisplayName));

            return(success);
        }
コード例 #4
0
        bool IHierarchical.AddChild(object child)
        {
            if (DomNode.Parent == null)
            {
                return(false);
            }

            ChildInfo chInfo = DomNode.ChildInfo;
            Slot      slot   = new Slot(this.DomNode.Parent, chInfo);
            bool      added  = slot.AddChild(child);

            if (added && chInfo.IsList)
            {
                DomNode.RemoveFromParent();
            }
            return(added);
        }
コード例 #5
0
        public void TestDomChangesInTransaction()
        {
            DomNode child      = m_root.GetChild(ChildInfo);
            DomNode grandchild = child.GetChild(ChildInfo);

            // Remove and then add the parent of the DomNode whose attributes get changed.
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetAttribute(StringAttrInfo, "foo1");
                grandchild.SetAttribute(StringAttrInfo, "foo2");
                grandchild.SetAttribute(StringAttrInfo, "foo3");
                child.RemoveFromParent();
                m_root.SetChild(ChildInfo, child);
                grandchild.SetAttribute(StringAttrInfo, "foo4");
            }, "test transaction");

            Assert.IsTrue(m_events.Count == 2);
            CheckChildRemovedEvent(m_events[0], m_root, child);
            CheckChildInsertedEvent(m_events[1], m_root, child);
        }
コード例 #6
0
        /// <summary>
        /// Synchronize two files
        /// </summary>
        /// <param name="domNodeProjTree">First file</param>
        /// <param name="domNodeTempTree">Second file</param>
        public static void SyncFiles(DomNode domNodeProjTree, DomNode domNodeTempTree)
        {
            var parent = domNodeProjTree.Parent;

            domNodeProjTree.RemoveFromParent();

            var clone = DomNode.Copy(new[] { domNodeTempTree });

            clone[0].InitializeExtensions();

            var info = domNodeTempTree.ChildInfo;

            if (info.IsList)
            {
                parent.GetChildList(info).Add(clone[0]);
            }
            else
            {
                parent.SetChild(info, clone[0]);
            }
        }
コード例 #7
0
        public void TestDomChangesNoTransaction()
        {
            DomNode child      = m_root.GetChild(ChildInfo);
            DomNode grandchild = child.GetChild(ChildInfo);

            grandchild.SetAttribute(StringAttrInfo, "foo1");
            grandchild.SetAttribute(StringAttrInfo, "foo2");
            grandchild.SetAttribute(StringAttrInfo, "foo3");
            child.RemoveFromParent();
            m_root.SetChild(ChildInfo, child);
            grandchild.SetAttribute(StringAttrInfo, "foo4");

            // Because there's no transaction, each DOM change event should yield a TransactionFinishedXxx event.
            Assert.IsTrue(m_events.Count == 6);
            CheckAttributeEvent(m_events[0], grandchild, "", "foo1");
            CheckAttributeEvent(m_events[1], grandchild, "foo1", "foo2");
            CheckAttributeEvent(m_events[2], grandchild, "foo2", "foo3");
            CheckChildRemovedEvent(m_events[3], m_root, child);
            CheckChildInsertedEvent(m_events[4], m_root, child);
            CheckAttributeEvent(m_events[5], grandchild, "foo3", "foo4");
        }
コード例 #8
0
ファイル: TestDomNode.cs プロジェクト: truongascii/ATF
        public void TestRemoveFromParent()
        {
            DomNodeType type      = new DomNodeType("type");
            ChildInfo   childInfo = new ChildInfo("child", type);

            type.Define(childInfo);
            DomNode parent = new DomNode(type);
            DomNode child  = new DomNode(type);

            parent.SetChild(childInfo, child);
            child.RemoveFromParent();
            Assert.Null(parent.GetChild(childInfo));
            Assert.Null(child.Parent);

            // Make sure the removed child has a null Parent. http://tracker.ship.scea.com/jira/browse/WWSATF-1336
            parent.SetChild(childInfo, child);
            DomNode newChild = new DomNode(type);

            parent.SetChild(childInfo, newChild);
            Assert.Null(child.Parent);
            Assert.True(newChild.Parent == parent);
        }
コード例 #9
0
        public void TestReparentInTransaction()
        {
            DomNode a = m_root.GetChild(ChildInfo);
            DomNode b = a.GetChild(ChildInfo);

            b.RemoveFromParent();

            // root -- a  ==>
            // root -- b -- a
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                a.SetAttribute(StringAttrInfo, "foo1");
                a.RemoveFromParent();
                m_root.SetChild(ChildInfo, b);
                b.SetChild(ChildInfo, a);
                b.SetAttribute(StringAttrInfo, "foo1");
            }, "test transaction 1");

            Assert.IsTrue(m_events.Count == 2);
            CheckChildRemovedEvent(m_events[0], m_root, a);
            CheckChildInsertedEvent(m_events[1], m_root, b);
        }
コード例 #10
0
        public void TestMoveDomNode()
        {
            var root = new DomNode(RootType.Type, RootElement);

            root.InitializeExtensions();

            var folderChild1 = new DomNode(FolderType.Type);
            var folderChild2 = new DomNode(FolderType.Type);
            var itemChild1 = new DomNode(ItemType.Type);
            var itemChild2 = new DomNode(ItemType.Type);

            var validationContext = root.As<ValidationContext>();
            
            // Set up the tree:
            // root
            //     folder
            //         item
            //     folder1
            //         item

            validationContext.RaiseBeginning();

            root.SetAttribute(RootType.NameAttribute, "root");
            itemChild1.SetAttribute(ItemType.NameAttribute, "item");
            itemChild2.SetAttribute(ItemType.NameAttribute, "item");
            folderChild1.SetAttribute(FolderType.NameAttribute, "folder");
            folderChild2.SetAttribute(FolderType.NameAttribute, "folder");

            folderChild1.GetChildList(FolderType.ItemChild).Add(itemChild1);
            folderChild2.GetChildList(FolderType.ItemChild).Add(itemChild2);

            root.GetChildList(RootType.FolderChild).Add(folderChild1);
            root.GetChildList(RootType.FolderChild).Add(folderChild2);

            // renames all folders and items with unique paths
            validationContext.RaiseEnding();
            validationContext.RaiseEnded(); 

            // Move item from first folder to second folder
            // root
            //     folder
            //     folder1
            //         item
            //         item1

            validationContext.RaiseBeginning();

            itemChild1.RemoveFromParent();
            folderChild2.GetChildList(FolderType.ItemChild).Add(itemChild1);

            validationContext.RaiseEnding();
            validationContext.RaiseEnded();
            Assert.DoesNotThrow(() => ValidateSubtree(folderChild2));
            // Make sure that the existing child wasn't renamed. Only the moved child should be renamed.
            Assert.True((string)itemChild2.GetAttribute(ItemType.NameAttribute) == "item");

            // Rename 'item_1' to 'item'.
            validationContext.RaiseBeginning();

            itemChild1.SetAttribute(ItemType.NameAttribute, "item");

            validationContext.RaiseEnding();
            validationContext.RaiseEnded();
            Assert.DoesNotThrow(() => ValidateSubtree(folderChild2));

            // Make sure that the existing child wasn't renamed. Only the moved child should be renamed.
            Assert.True((string)itemChild2.GetAttribute(ItemType.NameAttribute) == "item");

            // Rename the root.
            validationContext.RaiseBeginning();

            root.SetAttribute(RootType.NameAttribute, "new_root");

            validationContext.RaiseEnding();
            validationContext.RaiseEnded();
            Assert.DoesNotThrow(() => ValidateSubtree(root));
            Assert.True((string)root.GetAttribute(RootType.NameAttribute) == "new_root");
        }
コード例 #11
0
ファイル: TestDomNode.cs プロジェクト: cococo111111/ATF
 public void TestRemoveFromParentList()
 {
     DomNodeType type = new DomNodeType("type");
     ChildInfo childInfo = new ChildInfo("child", type, true);
     type.Define(childInfo);
     DomNode parent = new DomNode(type);
     DomNode child = new DomNode(type);
     parent.GetChildList(childInfo).Add(child);
     child.RemoveFromParent();
     CollectionAssert.IsEmpty(parent.Children);
     Assert.Null(child.Parent);
 }
コード例 #12
0
ファイル: TestDomNode.cs プロジェクト: cococo111111/ATF
        public void TestRemoveFromParent()
        {
            DomNodeType type = new DomNodeType("type");
            ChildInfo childInfo = new ChildInfo("child", type);
            type.Define(childInfo);
            DomNode parent = new DomNode(type);
            DomNode child = new DomNode(type);
            parent.SetChild(childInfo, child);
            child.RemoveFromParent();
            Assert.Null(parent.GetChild(childInfo));
            Assert.Null(child.Parent);

            // Make sure the removed child has a null Parent. http://tracker.ship.scea.com/jira/browse/WWSATF-1336
            parent.SetChild(childInfo, child);
            DomNode newChild = new DomNode(type);
            parent.SetChild(childInfo, newChild);
            Assert.Null(child.Parent);
            Assert.True(newChild.Parent == parent);
        }
コード例 #13
0
ファイル: TestTransactionReporter.cs プロジェクト: Joxx0r/ATF
        public void TestAddChildAndModifyInTransaction()
        {
            DomNode child = m_root.GetChild(ChildInfo);
            DomNode grandchild = child.GetChild(ChildInfo);
            var greatGrandchild = new DomNode(ChildType, ChildInfo);

            // Add a great-grandchild and then modify it. The attribute changed events should be ignored.
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);
                greatGrandchild.SetAttribute(StringAttrInfo, "foo1");
            }, "test transaction 1");

            Assert.IsTrue(m_events.Count == 1);
            CheckChildInsertedEvent(m_events[0], grandchild, greatGrandchild);

            // Make sure the TransactionReporter's state gets cleared for the next transaction.
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, null);//remove great-grandchild
                greatGrandchild.SetChild(ChildInfo, new DomNode(ChildType));
                grandchild.SetChild(ChildInfo, greatGrandchild);//insert great-grandchild (and its child)
                greatGrandchild.SetAttribute(StringAttrInfo, "foo2");
                greatGrandchild.GetChild(ChildInfo).SetAttribute(StringAttrInfo, "child foo2");
            }, "test transaction 2");
            Assert.IsTrue(m_events.Count == 2);
            CheckChildRemovedEvent(m_events[0], grandchild, greatGrandchild);
            CheckChildInsertedEvent(m_events[1], grandchild, greatGrandchild);

            // This time, make sure that removing the child of a newly inserted tree doesn't generate new events.
            greatGrandchild.RemoveFromParent();
            var great2Grandchild = new DomNode(ChildType);
            greatGrandchild.SetChild(ChildInfo, great2Grandchild);
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);//insert great-grandchild and great2Grandchild
                greatGrandchild.SetAttribute(StringAttrInfo, "foo3");
                great2Grandchild.SetAttribute(StringAttrInfo, "foo3");
                great2Grandchild.RemoveFromParent();
            }, "test transaction 3");
            Assert.IsTrue(m_events.Count == 1);
            CheckChildInsertedEvent(m_events[0], grandchild, greatGrandchild);

            // This time, make sure that removing two children of a newly inserted tree doesn't generate new events.
            grandchild.SetChild(ChildInfo, null);
            greatGrandchild.SetChild(ChildInfo, great2Grandchild);
            var great3Grandchild = new DomNode(ChildType);
            great2Grandchild.SetChild(ChildInfo, great3Grandchild);
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);
                greatGrandchild.SetAttribute(StringAttrInfo, "foo4");
                great2Grandchild.SetAttribute(StringAttrInfo, "foo4");
                great3Grandchild.SetAttribute(StringAttrInfo, "foo4");
                great3Grandchild.RemoveFromParent();
                great2Grandchild.RemoveFromParent();
            }, "test transaction 4");
            Assert.IsTrue(m_events.Count == 1);
            CheckChildInsertedEvent(m_events[0], grandchild, greatGrandchild);

            // Check that removing all the inserted children generates no events.
            grandchild.SetChild(ChildInfo, null);
            greatGrandchild.SetChild(ChildInfo, great2Grandchild);
            great2Grandchild.SetChild(ChildInfo, great3Grandchild);
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);
                greatGrandchild.SetAttribute(StringAttrInfo, "foo5");
                great2Grandchild.SetAttribute(StringAttrInfo, "foo5");
                great3Grandchild.SetAttribute(StringAttrInfo, "foo5");
                great3Grandchild.RemoveFromParent();
                great2Grandchild.RemoveFromParent();
                greatGrandchild.RemoveFromParent();
            }, "test transaction 5");
            Assert.IsTrue(m_events.Count == 0);
        }
コード例 #14
0
ファイル: GameContext.cs プロジェクト: coreafive/XLE
        /// <summary>
        /// Inserts the specified child into the specified parent</summary>
        /// <param name="parent">Parent to insert into</param>
        /// <param name="child">Child to be inserted</param>
        /// <remarks>This method is used by copy-paste and drag-drop from various sources.
        /// When making any changes to this method, please test the following:
        /// - Copy/Paste, Cut/Paste
        /// - Drag-drop from {Palette|ResourceLister} to {ProjectLister|DesignView}
        /// Pay special attention to:
        /// - (GameObjects with) GameObjectReferences
        /// - (GameObjects with) ResourceReferences incl. Locators
        /// - GameObjectGroups (and hierarchies thereof)
        /// - GameObjectFolders (and hierarchies thereof)
        /// - Pasting the same objects more than once</remarks>
        public void Insert(object parent, object child)
        {
            if (!CanInsert(parent, child))
            {
                return;
            }

            var hierarchical = parent.AsAll <IHierarchical>();

            // Extract node list from IDataObject
            IEnumerable <object> items = Util.ConvertData(child, true);

            DomNode parentRoot = null;
            DomNode parentNode = parent.As <DomNode>();

            if (parentNode != null)
            {
                parentRoot = parentNode.GetRoot();
            }

            List <DomNode> copyList   = new List <DomNode>();
            List <object>  objectlist = new List <object>();

            foreach (object item in items)
            {
                if (item.Is <IGameObject>() || item.Is <IGameObjectFolder>())
                {
                    DomNode childNode = item.As <DomNode>();
                    DomNode childRoot = childNode.GetRoot();

                    if ((parentRoot != null && childRoot.Is <IGame>() && parentRoot != childRoot))
                    {
                        childNode.RemoveFromParent();
                        copyList.Add(childNode);
                        continue;
                    }
                }
                objectlist.Add(item);
            }

            if (copyList.Count > 0)
            {
                IEnumerable <DomNode> copies = DomNode.Copy(copyList);
                // remvoe lock
                foreach (DomNode copy in copies)
                {
                    this.SetLocked(copy, false);
                }
                objectlist.AddRange(copies);
            }

            foreach (object obj in objectlist)
            {
                DomNode node = obj.As <DomNode>();
                if (node != null)
                {
                    node.InitializeExtensions();
                }
            }

            List <DomNode> insertedNodes = new List <DomNode>();

            foreach (object obj in objectlist)
            {
                object insertedObj = null;

                bool inserted = false;
                foreach (var h in hierarchical)
                {
                    if (h.AddChild(obj))
                    {
                        inserted = true;
                        break;
                    }
                }

                if (inserted)
                {
                    insertedObj = obj;
                }
                else
                {
                    IResource res = obj as IResource;
                    var       gob = m_resourceConverterService.Convert(res);
                    foreach (var h in hierarchical)
                    {
                        if (h.AddChild(gob))
                        {
                            inserted = true;
                            break;
                        }
                    }
                    if (inserted)
                    {
                        insertedObj = gob;
                    }
                }
                DomNode insertNode = Adapters.As <DomNode>(insertedObj);
                if (insertNode != null)
                {
                    insertedNodes.Add(insertNode);
                }
            }

            IEnumerable <DomNode> rootDomNodes = DomNode.GetRoots(insertedNodes);
            List <object>         newSelection = new List <object>();

            foreach (DomNode rootNode in rootDomNodes)
            {
                AdaptablePath <object> path = Util.AdaptDomPath(rootNode);

                if (path.First.Is <IGame>() && (rootNode.Is <IGameObject>() || rootNode.Is <IGameObjectFolder>()))
                {
                    newSelection.Add(path);
                }
            }
            if (newSelection.Count > 0)
            {
                if (InTransaction)
                {
                    m_savedSelection = new List <object>(MasterContext.Selection);
                }

                MasterContext.SetRange(newSelection);
            }
        }
コード例 #15
0
        public void TestMoveDomNode()
        {
            var root = new DomNode(RootType.Type, RootElement);

            root.InitializeExtensions();

            var folderChild1 = new DomNode(FolderType.Type);
            var folderChild2 = new DomNode(FolderType.Type);
            var itemChild1   = new DomNode(ItemType.Type);
            var itemChild2   = new DomNode(ItemType.Type);

            var validationContext = root.As <ValidationContext>();

            // Set up the tree:
            // root
            //     folder
            //         item
            //     folder1
            //         item

            validationContext.RaiseBeginning();

            root.SetAttribute(RootType.NameAttribute, "root");
            itemChild1.SetAttribute(ItemType.NameAttribute, "item");
            itemChild2.SetAttribute(ItemType.NameAttribute, "item");
            folderChild1.SetAttribute(FolderType.NameAttribute, "folder");
            folderChild2.SetAttribute(FolderType.NameAttribute, "folder");

            folderChild1.GetChildList(FolderType.ItemChild).Add(itemChild1);
            folderChild2.GetChildList(FolderType.ItemChild).Add(itemChild2);

            root.GetChildList(RootType.FolderChild).Add(folderChild1);
            root.GetChildList(RootType.FolderChild).Add(folderChild2);

            // renames all folders and items with unique paths
            validationContext.RaiseEnding();
            validationContext.RaiseEnded();

            // Move item from first folder to second folder
            // root
            //     folder
            //     folder1
            //         item
            //         item1

            validationContext.RaiseBeginning();

            itemChild1.RemoveFromParent();
            folderChild2.GetChildList(FolderType.ItemChild).Add(itemChild1);

            validationContext.RaiseEnding();
            validationContext.RaiseEnded();
            Assert.DoesNotThrow(() => ValidateSubtree(folderChild2));
            // Make sure that the existing child wasn't renamed. Only the moved child should be renamed.
            Assert.True((string)itemChild2.GetAttribute(ItemType.NameAttribute) == "item");

            // Rename 'item_1' to 'item'.
            validationContext.RaiseBeginning();

            itemChild1.SetAttribute(ItemType.NameAttribute, "item");

            validationContext.RaiseEnding();
            validationContext.RaiseEnded();
            Assert.DoesNotThrow(() => ValidateSubtree(folderChild2));

            // Make sure that the existing child wasn't renamed. Only the moved child should be renamed.
            Assert.True((string)itemChild2.GetAttribute(ItemType.NameAttribute) == "item");

            // Rename the root.
            validationContext.RaiseBeginning();

            root.SetAttribute(RootType.NameAttribute, "new_root");

            validationContext.RaiseEnding();
            validationContext.RaiseEnded();
            Assert.DoesNotThrow(() => ValidateSubtree(root));
            Assert.True((string)root.GetAttribute(RootType.NameAttribute) == "new_root");
        }
コード例 #16
0
        public void TestAddChildAndModifyInTransaction()
        {
            DomNode child           = m_root.GetChild(ChildInfo);
            DomNode grandchild      = child.GetChild(ChildInfo);
            var     greatGrandchild = new DomNode(ChildType, ChildInfo);

            // Add a great-grandchild and then modify it. The attribute changed events should be ignored.
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);
                greatGrandchild.SetAttribute(StringAttrInfo, "foo1");
            }, "test transaction 1");

            Assert.IsTrue(m_events.Count == 1);
            CheckChildInsertedEvent(m_events[0], grandchild, greatGrandchild);

            // Make sure the TransactionReporter's state gets cleared for the next transaction.
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, null);            //remove great-grandchild
                greatGrandchild.SetChild(ChildInfo, new DomNode(ChildType));
                grandchild.SetChild(ChildInfo, greatGrandchild); //insert great-grandchild (and its child)
                greatGrandchild.SetAttribute(StringAttrInfo, "foo2");
                greatGrandchild.GetChild(ChildInfo).SetAttribute(StringAttrInfo, "child foo2");
            }, "test transaction 2");
            Assert.IsTrue(m_events.Count == 2);
            CheckChildRemovedEvent(m_events[0], grandchild, greatGrandchild);
            CheckChildInsertedEvent(m_events[1], grandchild, greatGrandchild);

            // This time, make sure that removing the child of a newly inserted tree doesn't generate new events.
            greatGrandchild.RemoveFromParent();
            var great2Grandchild = new DomNode(ChildType);

            greatGrandchild.SetChild(ChildInfo, great2Grandchild);
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);//insert great-grandchild and great2Grandchild
                greatGrandchild.SetAttribute(StringAttrInfo, "foo3");
                great2Grandchild.SetAttribute(StringAttrInfo, "foo3");
                great2Grandchild.RemoveFromParent();
            }, "test transaction 3");
            Assert.IsTrue(m_events.Count == 1);
            CheckChildInsertedEvent(m_events[0], grandchild, greatGrandchild);

            // This time, make sure that removing two children of a newly inserted tree doesn't generate new events.
            grandchild.SetChild(ChildInfo, null);
            greatGrandchild.SetChild(ChildInfo, great2Grandchild);
            var great3Grandchild = new DomNode(ChildType);

            great2Grandchild.SetChild(ChildInfo, great3Grandchild);
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);
                greatGrandchild.SetAttribute(StringAttrInfo, "foo4");
                great2Grandchild.SetAttribute(StringAttrInfo, "foo4");
                great3Grandchild.SetAttribute(StringAttrInfo, "foo4");
                great3Grandchild.RemoveFromParent();
                great2Grandchild.RemoveFromParent();
            }, "test transaction 4");
            Assert.IsTrue(m_events.Count == 1);
            CheckChildInsertedEvent(m_events[0], grandchild, greatGrandchild);

            // Check that removing all the inserted children generates no events.
            grandchild.SetChild(ChildInfo, null);
            greatGrandchild.SetChild(ChildInfo, great2Grandchild);
            great2Grandchild.SetChild(ChildInfo, great3Grandchild);
            m_events.Clear();
            m_transactionContext.DoTransaction(() =>
            {
                grandchild.SetChild(ChildInfo, greatGrandchild);
                greatGrandchild.SetAttribute(StringAttrInfo, "foo5");
                great2Grandchild.SetAttribute(StringAttrInfo, "foo5");
                great3Grandchild.SetAttribute(StringAttrInfo, "foo5");
                great3Grandchild.RemoveFromParent();
                great2Grandchild.RemoveFromParent();
                greatGrandchild.RemoveFromParent();
            }, "test transaction 5");
            Assert.IsTrue(m_events.Count == 0);
        }