diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index 90c83b900..dfb909610 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -94,6 +94,7 @@
+
OpenFromGacDialog.xaml
Code
diff --git a/ILSpy/MainWindow.xaml b/ILSpy/MainWindow.xaml
index 6688e44e7..7d1f59090 100644
--- a/ILSpy/MainWindow.xaml
+++ b/ILSpy/MainWindow.xaml
@@ -26,6 +26,14 @@
+
+
@@ -78,6 +86,13 @@
+
+
+
@@ -115,7 +130,7 @@
+ Text="{Binding FilterSettings.SearchTerm, UpdateSourceTrigger=PropertyChanged}" />
partial class MainWindow : Window
{
+ NavigationHistory history = new NavigationHistory();
ILSpySettings spySettings;
SessionSettings sessionSettings;
AssemblyListManager assemblyListManager;
@@ -134,11 +136,14 @@ namespace ICSharpCode.ILSpy
void ShowAssemblyList(AssemblyList assemblyList)
{
+ history.Clear();
this.assemblyList = assemblyList;
+ assemblyList.Assemblies.CollectionChanged += assemblyList_Assemblies_CollectionChanged;
+
assemblyListTreeNode = new AssemblyListTreeNode(assemblyList);
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
- assemblyListTreeNode.Select = SelectNode;
+ assemblyListTreeNode.Select = node => SelectNode(node);
treeView.Root = assemblyListTreeNode;
if (assemblyList.ListName == AssemblyListManager.DefaultListName)
@@ -146,6 +151,13 @@ namespace ICSharpCode.ILSpy
else
this.Title = "ILSpy - " + assemblyList.ListName;
}
+
+ void assemblyList_Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.OldItems != null)
+ foreach (AssemblyTreeNode node in e.OldItems)
+ history.RemoveAll(n => n.AncestorsAndSelf().Contains(node));
+ }
void LoadInitialAssemblies()
{
@@ -186,9 +198,13 @@ namespace ICSharpCode.ILSpy
get { return assemblyList; }
}
- internal void SelectNode(SharpTreeNode obj)
+ #region Node Selection
+ internal void SelectNode(SharpTreeNode obj, bool recordNavigationInHistory = true)
{
if (obj != null) {
+ SharpTreeNode oldNode = treeView.SelectedItem as SharpTreeNode;
+ if (oldNode != null && recordNavigationInHistory)
+ history.Record(oldNode);
// Set both the selection and focus to ensure that keyboard navigation works as expected.
treeView.FocusNode(obj);
treeView.SelectedItem = obj;
@@ -232,6 +248,7 @@ namespace ICSharpCode.ILSpy
path.Reverse();
return path.ToArray();
}
+ #endregion
#region Debugging CFG
#if DEBUG
@@ -293,6 +310,7 @@ namespace ICSharpCode.ILSpy
#endif
#endregion
+ #region Open/Refresh
void OpenCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
@@ -317,7 +335,7 @@ namespace ICSharpCode.ILSpy
}
}
if (lastNode != null)
- treeView.ScrollIntoView(lastNode);
+ treeView.FocusNode(lastNode);
}
void RefreshCommandExecuted(object sender, ExecutedRoutedEventArgs e)
@@ -328,6 +346,17 @@ namespace ICSharpCode.ILSpy
SelectNode(FindNodeByPath(path, true));
}
+ void OpenFromGac_Click(object sender, RoutedEventArgs e)
+ {
+ OpenFromGacDialog dlg = new OpenFromGacDialog();
+ dlg.Owner = this;
+ if (dlg.ShowDialog() == true) {
+ OpenFiles(dlg.SelectedFileNames);
+ }
+ }
+ #endregion
+
+ #region Exit/About
void ExitClick(object sender, RoutedEventArgs e)
{
Close();
@@ -337,16 +366,9 @@ namespace ICSharpCode.ILSpy
{
AboutPage.Display(decompilerTextView);
}
+ #endregion
- void OpenFromGac_Click(object sender, RoutedEventArgs e)
- {
- OpenFromGacDialog dlg = new OpenFromGacDialog();
- dlg.Owner = this;
- if (dlg.ShowDialog() == true) {
- OpenFiles(dlg.SelectedFileNames);
- }
- }
-
+ #region Decompile / Save
void TreeView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (treeView.SelectedItems.Count == 1) {
@@ -370,6 +392,37 @@ namespace ICSharpCode.ILSpy
treeView.GetTopLevelSelection().OfType(),
new DecompilationOptions());
}
+ #endregion
+
+ #region Back/Forward navigation
+ void BackCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
+ {
+ e.Handled = true;
+ e.CanExecute = history.CanNavigateBack;
+ }
+
+ void BackCommandExecuted(object sender, ExecutedRoutedEventArgs e)
+ {
+ if (history.CanNavigateBack) {
+ e.Handled = true;
+ SelectNode(history.GoBack(treeView.SelectedItem as SharpTreeNode), false);
+ }
+ }
+
+ void ForwardCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
+ {
+ e.Handled = true;
+ e.CanExecute = history.CanNavigateForward;
+ }
+
+ void ForwardCommandExecuted(object sender, ExecutedRoutedEventArgs e)
+ {
+ if (history.CanNavigateForward) {
+ e.Handled = true;
+ SelectNode(history.GoForward(treeView.SelectedItem as SharpTreeNode), false);
+ }
+ }
+ #endregion
protected override void OnStateChanged(EventArgs e)
{
diff --git a/ILSpy/NavigationHistory.cs b/ILSpy/NavigationHistory.cs
new file mode 100644
index 000000000..521780af1
--- /dev/null
+++ b/ILSpy/NavigationHistory.cs
@@ -0,0 +1,64 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.TreeView;
+
+namespace ICSharpCode.ILSpy
+{
+ ///
+ /// Stores the navigation history.
+ ///
+ public class NavigationHistory
+ {
+ List back = new List();
+ List forward = new List();
+
+ public bool CanNavigateBack {
+ get { return back.Count > 0; }
+ }
+
+ public bool CanNavigateForward {
+ get { return forward.Count > 0; }
+ }
+
+ public SharpTreeNode GoBack(SharpTreeNode oldNode)
+ {
+ if (oldNode != null)
+ forward.Add(oldNode);
+
+ SharpTreeNode node = back[back.Count - 1];
+ back.RemoveAt(back.Count - 1);
+ return node;
+ }
+
+ public SharpTreeNode GoForward(SharpTreeNode oldNode)
+ {
+ if (oldNode != null)
+ back.Add(oldNode);
+
+ SharpTreeNode node = forward[forward.Count - 1];
+ forward.RemoveAt(forward.Count - 1);
+ return node;
+ }
+
+ public void RemoveAll(Predicate predicate)
+ {
+ back.RemoveAll(predicate);
+ forward.RemoveAll(predicate);
+ }
+
+ public void Clear()
+ {
+ back.Clear();
+ forward.Clear();
+ }
+
+ public void Record(SharpTreeNode node)
+ {
+ forward.Clear();
+ back.Add(node);
+ }
+ }
+}
diff --git a/SharpTreeView/SharpTreeView.cs b/SharpTreeView/SharpTreeView.cs
index 7a949b618..43ec4141a 100644
--- a/SharpTreeView/SharpTreeView.cs
+++ b/SharpTreeView/SharpTreeView.cs
@@ -198,6 +198,9 @@ namespace ICSharpCode.TreeView
base.OnKeyDown(e);
}
+ ///
+ /// Scrolls the specified node in view and sets keyboard focus on it.
+ ///
public void FocusNode(SharpTreeNode node)
{
if (node == null)