Index: Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeNodeExpandCollapseState.cs =================================================================== diff -u -reab6a10ef5444e79f4dddd5babbfcd5892d3d97a -r0685466b69cae089e6a1713f4ae437760f706fec --- Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeNodeExpandCollapseState.cs (.../TreeNodeExpandCollapseState.cs) (revision eab6a10ef5444e79f4dddd5babbfcd5892d3d97a) +++ Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeNodeExpandCollapseState.cs (.../TreeNodeExpandCollapseState.cs) (revision 0685466b69cae089e6a1713f4ae437760f706fec) @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; using Core.Common.Controls.Swf.Properties; @@ -38,7 +37,7 @@ throw new ArgumentException(Resources.TreeNodeExpandCollapseState_Node_tag_cannot_be_null_for_record_to_work); } wasExpanded = nodeToBeRecorded.IsExpanded; - childStates = nodeToBeRecorded.Nodes.Where(n => n.Nodes.Any()).ToDictionary(n => n.Tag, n => new TreeNodeExpandCollapseState(n), new ReferenceComparer()); + childStates = nodeToBeRecorded.Nodes.Where(n => n.Nodes.Any()).ToDictionary(n => n.Tag, n => new TreeNodeExpandCollapseState(n)); } /// @@ -71,33 +70,10 @@ } } - foreach (var treeNode in targetNode.Nodes.Where(n => n.Nodes.Any())) + foreach (var treeNode in targetNode.Nodes.Where(n => n.Nodes.Any() && childStates.ContainsKey(n.Tag))) { childStates[treeNode.Tag].Restore(treeNode); } } - - /// - /// Comparer based on object references. - /// - /// This class well suited to be used hashing objects into a - /// or implementations if one want to index these - /// collections on object instances which may have a custom implementation. - private class ReferenceComparer : IEqualityComparer - { - public new bool Equals(object x, object y) - { - return ReferenceEquals(x, y); - } - - public int GetHashCode(object obj) - { - if (obj == null) - { - throw new ArgumentNullException("obj"); - } - return RuntimeHelpers.GetHashCode(obj); - } - } } } \ No newline at end of file Index: Core/Common/test/Core.Common.Controls.Swf.Test/TreeViewControls/TreeNodeExpandCollapseStateTest.cs =================================================================== diff -u -reab6a10ef5444e79f4dddd5babbfcd5892d3d97a -r0685466b69cae089e6a1713f4ae437760f706fec --- Core/Common/test/Core.Common.Controls.Swf.Test/TreeViewControls/TreeNodeExpandCollapseStateTest.cs (.../TreeNodeExpandCollapseStateTest.cs) (revision eab6a10ef5444e79f4dddd5babbfcd5892d3d97a) +++ Core/Common/test/Core.Common.Controls.Swf.Test/TreeViewControls/TreeNodeExpandCollapseStateTest.cs (.../TreeNodeExpandCollapseStateTest.cs) (revision 0685466b69cae089e6a1713f4ae437760f706fec) @@ -44,7 +44,7 @@ } [Test] - public void RestoreState_SingleNodeCollapsed_CollapseNode() + public void Restore_SingleNodeCollapsed_CollapseNode() { // Setup var sourceData = new object(); @@ -73,7 +73,7 @@ } [Test] - public void RestoreState_SingleNodeExpanded_ExpandNode() + public void Restore_SingleNodeExpanded_ExpandNode() { // Setup var sourceData = new object(); @@ -104,7 +104,7 @@ [Test] [TestCase(true)] [TestCase(false)] - public void RestoreState_SingleNodeAndTargetInSameState_DoNothing(bool isExpanded) + public void Restore_SingleNodeAndTargetInSameState_DoNothing(bool isExpanded) { // Setup var sourceData = new object(); @@ -277,7 +277,7 @@ } [Test] - public void Restore_SourceTreeDifferentFromTargetTree_ThrowKeyNotFoundException() + public void Restore_NodeWithChildAddedAfterRecordingState_IgnoreChild() { // Setup var sourceData = new object(); @@ -296,7 +296,6 @@ var targetChildNode = mocks.StrictMock(); targetChildNode.Stub(n => n.Tag).Return(childData); - targetChildNode.Stub(n => n.IsExpanded).Return(true); targetChildNode.Stub(n => n.Nodes).Return(new List { stubNode @@ -315,11 +314,71 @@ var nodeState = new TreeNodeExpandCollapseState(sourceNode); // Call - TestDelegate call = () => nodeState.Restore(targetNode); + nodeState.Restore(targetNode); // Assert - Assert.Throws(call); mocks.VerifyAll(); } + + [Test] + public void Restore_NodeWithDifferentEqualDataInstances_RestoreState() + { + // Setup + var data1 = new IntegerWrapperWithCustomEquals + { + WrappedInteger = 1 + }; + var data2 = new IntegerWrapperWithCustomEquals + { + WrappedInteger = 1 + }; + + var mocks = new MockRepository(); + var sourceNode = mocks.StrictMock(); + sourceNode.Expect(n => n.IsExpanded).Return(false); + sourceNode.Expect(n => n.Tag).Return(data1); + sourceNode.Stub(n => n.Nodes).Return(new List()); + + var targetNode = mocks.StrictMock(); + targetNode.Expect(n => n.IsExpanded).Return(true); + targetNode.Expect(n => n.Tag).Return(data2); + targetNode.Expect(n => n.Collapse()); + targetNode.Stub(n => n.Nodes).Return(new List()); + + mocks.ReplayAll(); + + // Precondition: + Assert.True(data1.Equals(data2)); + Assert.True(data2.Equals(data1)); + Assert.AreNotSame(data1, data2); + + var nodeState = new TreeNodeExpandCollapseState(sourceNode); + + // Call + nodeState.Restore(targetNode); + + // Assert + mocks.VerifyAll(); + } + + private class IntegerWrapperWithCustomEquals + { + public int WrappedInteger { get; set; } + + public override bool Equals(object obj) + { + var otherIntWrapper = obj as IntegerWrapperWithCustomEquals; + if (otherIntWrapper != null) + { + return WrappedInteger.Equals(otherIntWrapper.WrappedInteger); + } + return base.Equals(obj); + } + + public override int GetHashCode() + { + return WrappedInteger.GetHashCode(); + } + } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/NodePresenters/PipingCalculationGroupContextNodePresenter.cs =================================================================== diff -u -reab6a10ef5444e79f4dddd5babbfcd5892d3d97a -r0685466b69cae089e6a1713f4ae437760f706fec --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/NodePresenters/PipingCalculationGroupContextNodePresenter.cs (.../PipingCalculationGroupContextNodePresenter.cs) (revision eab6a10ef5444e79f4dddd5babbfcd5892d3d97a) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/NodePresenters/PipingCalculationGroupContextNodePresenter.cs (.../PipingCalculationGroupContextNodePresenter.cs) (revision 0685466b69cae089e6a1713f4ae437760f706fec) @@ -375,19 +375,18 @@ /// before the drag & drop operation. protected virtual void UpdateTreeView(ITreeNode draggedNode, TreeNodeExpandCollapseState targetRecordedNodeState) { - HandlePostDragExpandCollapseOfNewOwner(draggedNode, targetRecordedNodeState); + HandlePostDragExpandCollapseOfNewOwner(draggedNode.Parent, targetRecordedNodeState); treeView.SelectedNode = draggedNode; } - private static void HandlePostDragExpandCollapseOfNewOwner(ITreeNode draggedNode, TreeNodeExpandCollapseState newOwnerRecordedNodeState) + private static void HandlePostDragExpandCollapseOfNewOwner(ITreeNode parentOfDraggedNode, TreeNodeExpandCollapseState newOwnerRecordedNodeState) { - ITreeNode newParentOfDraggedNode = draggedNode.Parent; - newOwnerRecordedNodeState.Restore(newParentOfDraggedNode); + newOwnerRecordedNodeState.Restore(parentOfDraggedNode); // Expand parent of 'draggedNode' to ensure 'draggedNode' is visible. - if (!newParentOfDraggedNode.IsExpanded) + if (!parentOfDraggedNode.IsExpanded) { - newParentOfDraggedNode.Expand(); + parentOfDraggedNode.Expand(); } } } @@ -436,7 +435,7 @@ var targetRecordedNodeState = new TreeNodeExpandCollapseState(treeView.GetNodeByTag(target)); recordedNodeState = new TreeNodeExpandCollapseState(treeView.GetNodeByTag(draggedDataObject)); - renamed = EnsureDraggedNodeHasUniqueNameInNewOwner(pipingCalculationItem, target); + EnsureDraggedNodeHasUniqueNameInNewOwner(pipingCalculationItem, target); MoveCalculationItemToNewOwner(pipingCalculationItem, newPosition); @@ -462,15 +461,14 @@ target.NotifyObservers(); } - private static bool EnsureDraggedNodeHasUniqueNameInNewOwner(IPipingCalculationItem pipingCalculationItem, PipingCalculationGroupContext newOwner) + private void EnsureDraggedNodeHasUniqueNameInNewOwner(IPipingCalculationItem pipingCalculationItem, PipingCalculationGroupContext newOwner) { - bool renamed = false; + renamed = false; string uniqueName = NamingHelper.GetUniqueName(newOwner.WrappedData.Children, pipingCalculationItem.Name, pci => pci.Name); if (!pipingCalculationItem.Name.Equals(uniqueName)) { renamed = TryRenameTo(pipingCalculationItem, uniqueName); } - return renamed; } private static bool TryRenameTo(IPipingCalculationItem pipingCalculationItem, string newName)