Index: Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeView.cs =================================================================== diff -u -rf43e90a16e94b36691e0ebb8e9ffa5989678b093 -r113fd0fac19ed2f327ae9faa016f25660785b5ce --- Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeView.cs (.../TreeView.cs) (revision f43e90a16e94b36691e0ebb8e9ffa5989678b093) +++ Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeView.cs (.../TreeView.cs) (revision 113fd0fac19ed2f327ae9faa016f25660785b5ce) @@ -292,7 +292,7 @@ } } - public void DeleteNodeData() + public void TryDeleteSelectedNodeData() { if (!SelectedNodeCanDelete()) { @@ -306,6 +306,11 @@ return; } + DeleteSelectedNodeData(); + } + + private void DeleteSelectedNodeData() + { var presenter = GetTreeViewNodePresenter(SelectedNode.Tag, SelectedNode); presenter.RemoveNodeData(SelectedNode.Parent.Tag, SelectedNode.Tag); SelectedNode = SelectedNode ?? Nodes.FirstOrDefault(); @@ -319,7 +324,6 @@ } BeginUpdate(); - try { var selectedNodePath = SelectedNode == null ? string.Empty : SelectedNode.FullPath; @@ -542,7 +546,7 @@ case Keys.Delete: if (OnProcessCmdKey == null && SelectedNode != null && SelectedNode.Tag != null) { - DeleteNodeData(); + TryDeleteSelectedNodeData(); return true; } break; Index: Core/Common/src/Core.Common.Controls/ITreeView.cs =================================================================== diff -u -r2a90c0c1be6114f72af65c42f0a6f334b30e4755 -r113fd0fac19ed2f327ae9faa016f25660785b5ce --- Core/Common/src/Core.Common.Controls/ITreeView.cs (.../ITreeView.cs) (revision 2a90c0c1be6114f72af65c42f0a6f334b30e4755) +++ Core/Common/src/Core.Common.Controls/ITreeView.cs (.../ITreeView.cs) (revision 113fd0fac19ed2f327ae9faa016f25660785b5ce) @@ -131,6 +131,6 @@ /// void StartLabelEdit(); - void DeleteNodeData(); + void TryDeleteSelectedNodeData(); } } \ No newline at end of file Index: Core/Common/test/Core.Common.Base.Tests/Controls/Swf/TreeViewControls/TreeViewTest.cs =================================================================== diff -u -r6a3a7c7e3442a1c99598c8f0fe7bd95062bc8845 -r113fd0fac19ed2f327ae9faa016f25660785b5ce --- Core/Common/test/Core.Common.Base.Tests/Controls/Swf/TreeViewControls/TreeViewTest.cs (.../TreeViewTest.cs) (revision 6a3a7c7e3442a1c99598c8f0fe7bd95062bc8845) +++ Core/Common/test/Core.Common.Base.Tests/Controls/Swf/TreeViewControls/TreeViewTest.cs (.../TreeViewTest.cs) (revision 113fd0fac19ed2f327ae9faa016f25660785b5ce) @@ -8,6 +8,7 @@ using Core.Common.Controls; using Core.Common.Controls.Swf.TreeViewControls; using Core.Common.TestUtils; +using Core.Common.Utils.Reflection; using NUnit.Framework; using Rhino.Mocks; using SharpTestsEx; @@ -310,7 +311,45 @@ treeView.Nodes[0].Nodes[0].IsExpanded.Should("node remains expanded").Be.True(); } + /// + /// If node deleted then selection should go to it's parent. In case, by some reason, there is no node selected after all selection should go to the very first node. + /// [Test] + public void DeletedNodeMovesSelectionToItsParentNode() + { + var treeView = new TreeView + { + NodePresenters = + { + new ParentNodePresenter(), // DynamicParentNodePresenter(), + new ChildNodePresenter() + } + }; + + var parent = new Parent() { Name = "Parent"}; + var child = new Child() { Name = "Child" }; + var grandchild = new Child() { Name = "GrandChild" }; + parent.Children.Add(child); + child.Children.Add(grandchild); + + treeView.Data = parent; + + WindowsFormsTestHelper.Show(treeView); // show it to make sure that expand / refresh node really loads nodes. + + treeView.ExpandAll(); + treeView.Refresh(); + + treeView.SelectedNode = treeView.GetNodeByTag(grandchild); + + TypeUtils.CallPrivateMethod(treeView, "DeleteSelectedNodeData"); + + treeView.ExpandAll(); + treeView.Refresh(); + + Assert.AreEqual(treeView.SelectedNode, treeView.GetNodeByTag(child)); + } + + [Test] public void TreeViewUpdateOnManyPropertyChangesShouldBeFast() { var parent = new Child Index: Core/Common/test/Core.Common.Base.Tests/TestObjects/Child.cs =================================================================== diff -u -r3debb2835679b29531ce363c17d5fde650cbdca3 -r113fd0fac19ed2f327ae9faa016f25660785b5ce --- Core/Common/test/Core.Common.Base.Tests/TestObjects/Child.cs (.../Child.cs) (revision 3debb2835679b29531ce363c17d5fde650cbdca3) +++ Core/Common/test/Core.Common.Base.Tests/TestObjects/Child.cs (.../Child.cs) (revision 113fd0fac19ed2f327ae9faa016f25660785b5ce) @@ -5,15 +5,38 @@ namespace Core.Common.Base.Tests.TestObjects { [Entity] - public class Child + public class Child : IObservable { + private readonly IList observers = new List(); + public Child() { Children = new EventedList(); } public string Name { get; set; } - public IList Children { get; set; } + + #region IObservable + + public void Attach(IObserver observer) + { + observers.Add(observer); + } + + public void Detach(IObserver observer) + { + observers.Remove(observer); + } + + public void NotifyObservers() + { + foreach (var observer in observers) + { + observer.UpdateObserver(); + } + } + + #endregion } } \ No newline at end of file Index: Core/Common/test/Core.Common.Base.Tests/TestObjects/ChildNodePresenter.cs =================================================================== diff -u -r3debb2835679b29531ce363c17d5fde650cbdca3 -r113fd0fac19ed2f327ae9faa016f25660785b5ce --- Core/Common/test/Core.Common.Base.Tests/TestObjects/ChildNodePresenter.cs (.../ChildNodePresenter.cs) (revision 3debb2835679b29531ce363c17d5fde650cbdca3) +++ Core/Common/test/Core.Common.Base.Tests/TestObjects/ChildNodePresenter.cs (.../ChildNodePresenter.cs) (revision 113fd0fac19ed2f327ae9faa016f25660785b5ce) @@ -9,6 +9,35 @@ { public event EventHandler AfterUpdate; + /// + /// Specifies if node can be deleted by user + /// + protected override bool CanRemove(Child nodeData) + { + return true; + } + + protected override bool RemoveNodeData(object parentNodeData, Child nodeData) + { + if (parentNodeData is Parent) + { + ((Parent)parentNodeData).Children.Remove(nodeData); + ((Parent)parentNodeData).NotifyObservers(); + } + else + { + if (parentNodeData is Child) + { + ((Child)parentNodeData).Children.Remove(nodeData); + ((Child)parentNodeData).NotifyObservers(); + } + } + + + + return true; + } + public override void UpdateNode(ITreeNode parentNode, ITreeNode node, Child nodeData) { node.Text = nodeData.Name; Index: Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectTreeView.cs =================================================================== diff -u -rce485d2ea1e537a2d9be33d46a282e5bfa2abdcc -r113fd0fac19ed2f327ae9faa016f25660785b5ce --- Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectTreeView.cs (.../ProjectTreeView.cs) (revision ce485d2ea1e537a2d9be33d46a282e5bfa2abdcc) +++ Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectTreeView.cs (.../ProjectTreeView.cs) (revision 113fd0fac19ed2f327ae9faa016f25660785b5ce) @@ -216,7 +216,7 @@ } if (keyData == Keys.Delete) { - treeView.DeleteNodeData(); + treeView.TryDeleteSelectedNodeData(); return true; } @@ -270,7 +270,7 @@ /// private void deleteMenuItemClick(object sender, EventArgs e) { - treeView.DeleteNodeData(); + treeView.TryDeleteSelectedNodeData(); } private void TreeViewDoubleClick(object sender, EventArgs e)