From daf973b0d5876fdf9c43be99f3ccd21a177c772c Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 7 Mar 2015 10:28:22 +0100 Subject: [PATCH] (SharpTreeView) fix #555: ILSpy crashes when deleting more than a screenful of assemblies --- SharpTreeView/SharpTreeView.cs | 37 +++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/SharpTreeView/SharpTreeView.cs b/SharpTreeView/SharpTreeView.cs index 96491052a..7069ad5cb 100644 --- a/SharpTreeView/SharpTreeView.cs +++ b/SharpTreeView/SharpTreeView.cs @@ -120,6 +120,7 @@ namespace ICSharpCode.TreeView } TreeFlattener flattener; + bool updatesLocked; void Reload() { @@ -148,18 +149,24 @@ namespace ICSharpCode.TreeView selectedOldItems.Add(node); } } - if (selectedOldItems != null) { + if (!updatesLocked && selectedOldItems != null) { var list = SelectedItems.Cast().Except(selectedOldItems).ToList(); - SetSelectedItems(list); - if (SelectedItem == null) { - // if we removed all selected nodes, then move the focus to the node - // preceding the first of the old selected nodes - SelectedIndex = Math.Max(0, e.OldStartingIndex - 1); - FocusNode((SharpTreeNode)SelectedItem); - } + UpdateFocusedNode(list, Math.Max(0, e.OldStartingIndex - 1)); } } } + + void UpdateFocusedNode(List newSelection, int topSelectedIndex) + { + if (updatesLocked) return; + SetSelectedItems(newSelection ?? Enumerable.Empty()); + if (SelectedItem == null) { + // if we removed all selected nodes, then move the focus to the node + // preceding the first of the old selected nodes + SelectedIndex = topSelectedIndex; + FocusNode((SharpTreeNode)SelectedItem); + } + } protected override DependencyObject GetContainerForItemOverride() { @@ -631,8 +638,18 @@ namespace ICSharpCode.TreeView static void HandleExecuted_Delete(object sender, ExecutedRoutedEventArgs e) { SharpTreeView treeView = (SharpTreeView)sender; - foreach (SharpTreeNode node in treeView.GetTopLevelSelection().ToArray()) - node.Delete(); + treeView.updatesLocked = true; + int selectedIndex = -1; + try { + foreach (SharpTreeNode node in treeView.GetTopLevelSelection().ToArray()) { + if (selectedIndex == -1) + selectedIndex = treeView.flattener.IndexOf(node); + node.Delete(); + } + } finally { + treeView.updatesLocked = false; + treeView.UpdateFocusedNode(null, Math.Max(0, selectedIndex - 1)); + } } static void HandleCanExecute_Delete(object sender, CanExecuteRoutedEventArgs e)