From a8def5bf85d2ba1a55b588a6ef194990fffce964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 09:50:37 +0100 Subject: [PATCH 1/7] Navigate visible history --- ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs | 5 ++ ILSpy/AssemblyTree/AssemblyTreeModel.cs | 23 +++-- ILSpy/Commands/BrowseBackCommand.cs | 13 ++- ILSpy/Commands/BrowseForwardCommand.cs | 11 ++- ILSpy/Commands/SimpleCommand.cs | 7 ++ ILSpy/Controls/MainToolBar.xaml.cs | 89 +++++++++++++++++++- ILSpy/Metadata/MetadataTreeNode.cs | 2 + ILSpy/NavigationHistory.cs | 3 + ILSpy/NavigationState.cs | 18 ++++ ILSpy/Themes/ThemeManager.cs | 6 ++ ILSpy/TreeNodes/BaseTypesTreeNode.cs | 2 + ILSpy/TreeNodes/DerivedTypesTreeNode.cs | 2 + ILSpy/TreeNodes/EventTreeNode.cs | 6 +- ILSpy/TreeNodes/FieldTreeNode.cs | 6 +- ILSpy/TreeNodes/MethodTreeNode.cs | 6 +- ILSpy/TreeNodes/PropertyTreeNode.cs | 6 +- ILSpy/TreeNodes/ReferenceFolderTreeNode.cs | 2 + ILSpy/TreeNodes/ResourceListTreeNode.cs | 2 + ILSpy/TreeNodes/TypeTreeNode.cs | 3 + 19 files changed, 193 insertions(+), 19 deletions(-) diff --git a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs index 8a86190802..7a735070c9 100644 --- a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs +++ b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs @@ -126,6 +126,11 @@ public virtual object? Text { get { return null; } } + public virtual object? NavigationText + { + get { return Text; } + } + public virtual object? Icon { get { return null; } } diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index c201179c14..8a0a390ed9 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -853,15 +853,24 @@ public void RefreshDecompiledView() #endregion - public void NavigateHistory(bool forward) + public void NavigateHistory(bool forward, NavigationState? toState = null) { try { - TabPageModel tabPage = DockWorkspace.ActiveTabPage; - var state = tabPage.GetState(); - if (state != null) - history.UpdateCurrent(new NavigationState(tabPage, state)); - var newState = forward ? history.GoForward() : history.GoBack(); + TabPageModel tabPage = DockWorkspace.ActiveTabPage; + var currentState = tabPage.GetState(); + if (currentState != null) + history.UpdateCurrent(new NavigationState(tabPage, currentState)); + + NavigationState newState; + do + { + newState = forward ? history.GoForward() : history.GoBack(); + } while (newState != null && toState != null && toState != newState); + + if (newState == null) + return; + navigatingToState = newState; TabPageModel activeTabPage = newState.TabPage; @@ -884,6 +893,8 @@ public void NavigateHistory(bool forward) } } + public NavigationState[] GetNavigateHistory(bool forward) => forward ? history.ForwardList : history.BackList; + public bool CanNavigateBack => history.CanNavigateBack; public bool CanNavigateForward => history.CanNavigateForward; diff --git a/ILSpy/Commands/BrowseBackCommand.cs b/ILSpy/Commands/BrowseBackCommand.cs index d52f4d7345..2c2e787986 100644 --- a/ILSpy/Commands/BrowseBackCommand.cs +++ b/ILSpy/Commands/BrowseBackCommand.cs @@ -16,7 +16,9 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Collections; using System.Composition; +using System.Linq; using System.Windows.Input; using ICSharpCode.ILSpy.AssemblyTree; @@ -26,7 +28,7 @@ namespace ICSharpCode.ILSpy { [ExportToolbarCommand(ToolTip = nameof(Resources.Back), ToolbarIcon = "Images/Back", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 0)] [Shared] - sealed class BrowseBackCommand : CommandWrapper + sealed class BrowseBackCommand : CommandWrapper, IProvideParameterList { readonly AssemblyTreeModel assemblyTreeModel; @@ -49,8 +51,15 @@ protected override void OnExecute(object sender, ExecutedRoutedEventArgs e) if (assemblyTreeModel.CanNavigateBack) { e.Handled = true; - assemblyTreeModel.NavigateHistory(false); + assemblyTreeModel.NavigateHistory(false, e.Parameter as NavigationState); } } + + public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(false).Reverse(); + + public object GetParamaterText(object parameter) + { + return (parameter as NavigationState)?.NavigationText; + } } } diff --git a/ILSpy/Commands/BrowseForwardCommand.cs b/ILSpy/Commands/BrowseForwardCommand.cs index 1eb2648568..74b42a1cd1 100644 --- a/ILSpy/Commands/BrowseForwardCommand.cs +++ b/ILSpy/Commands/BrowseForwardCommand.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Collections; using System.Composition; using System.Windows.Input; @@ -26,7 +27,7 @@ namespace ICSharpCode.ILSpy { [ExportToolbarCommand(ToolTip = nameof(Resources.Forward), ToolbarIcon = "Images/Forward", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 1)] [Shared] - sealed class BrowseForwardCommand : CommandWrapper + sealed class BrowseForwardCommand : CommandWrapper, IProvideParameterList { private readonly AssemblyTreeModel assemblyTreeModel; @@ -49,9 +50,15 @@ protected override void OnExecute(object sender, ExecutedRoutedEventArgs e) if (assemblyTreeModel.CanNavigateForward) { e.Handled = true; - assemblyTreeModel.NavigateHistory(true); + assemblyTreeModel.NavigateHistory(true, e.Parameter as NavigationState); } } + public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(true); + + public object GetParamaterText(object parameter) + { + return (parameter as NavigationState)?.NavigationText; + } } } diff --git a/ILSpy/Commands/SimpleCommand.cs b/ILSpy/Commands/SimpleCommand.cs index 19c1c7c9ec..da37bc81b4 100644 --- a/ILSpy/Commands/SimpleCommand.cs +++ b/ILSpy/Commands/SimpleCommand.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections; using System.Windows.Data; using System.Windows.Input; @@ -41,4 +42,10 @@ public interface IProvideParameterBinding { Binding ParameterBinding { get; } } + + public interface IProvideParameterList + { + IEnumerable ParameterList { get; } + object GetParamaterText(object parameter); + } } diff --git a/ILSpy/Controls/MainToolBar.xaml.cs b/ILSpy/Controls/MainToolBar.xaml.cs index 246d68d6c0..52f66a0df3 100644 --- a/ILSpy/Controls/MainToolBar.xaml.cs +++ b/ILSpy/Controls/MainToolBar.xaml.cs @@ -23,9 +23,11 @@ using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; +using System.Windows.Media; using System.Windows.Threading; using ICSharpCode.ILSpy.Themes; +using ICSharpCode.ILSpyX.TreeView; using TomsToolbox.Composition; @@ -85,7 +87,8 @@ static void InitToolbar(ToolBar toolBar, IExportProvider exportProvider) } } - static Button CreateToolbarItem(IExport commandExport) + + static UIElement CreateToolbarItem(IExport commandExport) { var command = commandExport.Value; @@ -108,9 +111,93 @@ static Button CreateToolbarItem(IExport comma parameterBinding.ParameterBinding); } + if (command is IProvideParameterList parameterList) + { + toolbarItem.Margin = new Thickness(2, 0, 0, 0); + + var dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal }; + + var contextMenu = new ContextMenu { + PlacementTarget = dropDownPanel, + Tag = command + }; + + ContextMenuService.SetPlacement(toolbarItem, PlacementMode.Bottom); + toolbarItem.ContextMenu = contextMenu; + toolbarItem.ContextMenuOpening += (_, _) => + PrepareParameterList(contextMenu); + + var dropDownToggle = new ToggleButton { + Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(), + Content = "▾", + Padding = new Thickness(0), + MinWidth = 0, + Margin = new Thickness(0, 0, 2, 0) + }; + + dropDownToggle.Checked += (_, _) => { + PrepareParameterList(contextMenu); + contextMenu.Placement = PlacementMode.Bottom; + contextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true); + }; + + BindingOperations.SetBinding(dropDownToggle, ToggleButton.IsCheckedProperty, + new Binding(nameof(contextMenu.IsOpen)) { Source = contextMenu }); + + BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty, + new Binding(nameof(IsEnabled)) { Source = toolbarItem }); + + dropDownPanel.Children.Add(toolbarItem); + dropDownPanel.Children.Add(dropDownToggle); + return dropDownPanel; + } + return toolbarItem; } + static void PrepareParameterList(ContextMenu menu) + { + const int maximumParameterListCount = 20; + + var command = (ICommand)menu.Tag; + var parameterList = (IProvideParameterList)command; + + menu.Items.Clear(); + foreach (var parameter in parameterList.ParameterList) + { + MenuItem parameterItem = new MenuItem(); + parameterItem.Command = CommandWrapper.Unwrap(command); + parameterItem.CommandParameter = parameter; + parameterItem.CommandTarget = menu.PlacementTarget; + parameterItem.InputGestureText = " "; + + var headerPresenter = new ContentPresenter { RecognizesAccessKey = false }; + parameterItem.Header = headerPresenter; + + var header = parameterList.GetParamaterText(parameter); + switch (header) + { + case SharpTreeNode node: + headerPresenter.Content = node.NavigationText; + if (node.Icon is ImageSource icon) + parameterItem.Icon = new Image { + Width = 16, + Height = 16, + Source = icon + }; + break; + + default: + headerPresenter.Content = header; + break; + } + + menu.Items.Add(parameterItem); + if (menu.Items.Count >= maximumParameterListCount) + break; + } + } + void MainWindow_KeyDown(object sender, KeyEventArgs e) { if (e.Handled || e.KeyboardDevice.Modifiers != ModifierKeys.Alt || e.Key != Key.System) diff --git a/ILSpy/Metadata/MetadataTreeNode.cs b/ILSpy/Metadata/MetadataTreeNode.cs index e4fe18b8c2..ac386c9436 100644 --- a/ILSpy/Metadata/MetadataTreeNode.cs +++ b/ILSpy/Metadata/MetadataTreeNode.cs @@ -45,6 +45,8 @@ public MetadataTreeNode(MetadataFile module, string title) public override object Text => title; + public override object NavigationText => metadataFile.Name + " " + Text; + public override object Icon => Images.Metadata; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/NavigationHistory.cs b/ILSpy/NavigationHistory.cs index 30f428a848..6e9f6ed703 100644 --- a/ILSpy/NavigationHistory.cs +++ b/ILSpy/NavigationHistory.cs @@ -34,6 +34,9 @@ internal sealed class NavigationHistory List back = new List(); List forward = new List(); + public T[] BackList => back.ToArray(); + public T[] ForwardList => forward.ToArray(); + public bool CanNavigateBack { get { return back.Count > 0; } } diff --git a/ILSpy/NavigationState.cs b/ILSpy/NavigationState.cs index 287b849cc8..dbd5545e26 100644 --- a/ILSpy/NavigationState.cs +++ b/ILSpy/NavigationState.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; @@ -62,5 +63,22 @@ public bool Equals(NavigationState other) return this.ViewState.Equals(other.ViewState); } + + public object NavigationText + { + get + { + if (this.treeNodes.Count == 1) + return this.treeNodes.First(); + + if (this.treeNodes.Count > 0) + return string.Join(", ", treeNodes.Select(tn => tn.NavigationText)); + + if (this.ViewState?.ViewedUri is Uri uri) + return uri; + + return ToString(); + } + } } } diff --git a/ILSpy/Themes/ThemeManager.cs b/ILSpy/Themes/ThemeManager.cs index 667fc83e6f..3b5b1f8ecd 100644 --- a/ILSpy/Themes/ThemeManager.cs +++ b/ILSpy/Themes/ThemeManager.cs @@ -24,6 +24,7 @@ using System.Linq; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Media; using ICSharpCode.AvalonEdit.Highlighting; @@ -81,6 +82,11 @@ public Style CreateToolBarButtonStyle() return new Style(typeof(Button), (Style)Application.Current.FindResource(ToolBar.ButtonStyleKey)); } + public Style CreateToolBarToggleButtonStyle() + { + return new Style(typeof(ToggleButton), (Style)Application.Current.FindResource(ToolBar.ToggleButtonStyleKey)); + } + public void ApplyHighlightingColors(IHighlightingDefinition highlightingDefinition) { // Make sure all color values are taken from the theme diff --git a/ILSpy/TreeNodes/BaseTypesTreeNode.cs b/ILSpy/TreeNodes/BaseTypesTreeNode.cs index 150408b7ff..f0726b4321 100644 --- a/ILSpy/TreeNodes/BaseTypesTreeNode.cs +++ b/ILSpy/TreeNodes/BaseTypesTreeNode.cs @@ -46,6 +46,8 @@ public BaseTypesTreeNode(MetadataFile module, ITypeDefinition type) public override object Text => Properties.Resources.BaseTypes; + public override object NavigationText => this.Language.TypeToString(type, includeNamespace: true) + " " + Text; + public override object Icon => Images.SuperTypes; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 21b471ea9f..5166f0758d 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -47,6 +47,8 @@ public DerivedTypesTreeNode(AssemblyList list, ITypeDefinition type) public override object Text => Resources.DerivedTypes; + public override object NavigationText => this.Language.TypeToString(type, includeNamespace: true) + " " + Text; + public override object Icon => Images.SubTypes; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/EventTreeNode.cs b/ILSpy/TreeNodes/EventTreeNode.cs index b03d16d4d5..1c10674e9f 100644 --- a/ILSpy/TreeNodes/EventTreeNode.cs +++ b/ILSpy/TreeNodes/EventTreeNode.cs @@ -49,6 +49,8 @@ public EventTreeNode(IEvent @event) public override object Text => GetText(GetEventDefinition(), this.Language) + GetSuffixString(EventDefinition); + public override object NavigationText => GetText(GetEventDefinition(), Language, includeDeclaringTypeName: true); + private IEvent GetEventDefinition() { return ((MetadataModule)EventDefinition.ParentModule?.MetadataFile @@ -56,9 +58,9 @@ private IEvent GetEventDefinition() ?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition; } - public static object GetText(IEvent ev, Language language) + public static object GetText(IEvent ev, Language language, bool includeDeclaringTypeName = false) { - return language.EventToString(ev, false, false, false); + return language.EventToString(ev, includeDeclaringTypeName, false, false); } public override object Icon => GetIcon(GetEventDefinition()); diff --git a/ILSpy/TreeNodes/FieldTreeNode.cs b/ILSpy/TreeNodes/FieldTreeNode.cs index ffd74e774a..1cf4b17b20 100644 --- a/ILSpy/TreeNodes/FieldTreeNode.cs +++ b/ILSpy/TreeNodes/FieldTreeNode.cs @@ -41,6 +41,8 @@ public FieldTreeNode(IField field) public override object Text => GetText(GetFieldDefinition(), Language) + GetSuffixString(FieldDefinition); + public override object NavigationText => GetText(GetFieldDefinition(), Language, includeDeclaringTypeName: true); + private IField GetFieldDefinition() { return ((MetadataModule)FieldDefinition.ParentModule?.MetadataFile @@ -48,9 +50,9 @@ private IField GetFieldDefinition() ?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition; } - public static object GetText(IField field, Language language) + public static object GetText(IField field, Language language, bool includeDeclaringTypeName = false) { - return language.FieldToString(field, includeDeclaringTypeName: false, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false); + return language.FieldToString(field, includeDeclaringTypeName, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false); } public override object Icon => GetIcon(GetFieldDefinition()); diff --git a/ILSpy/TreeNodes/MethodTreeNode.cs b/ILSpy/TreeNodes/MethodTreeNode.cs index c8522887e2..fc6d44ce60 100644 --- a/ILSpy/TreeNodes/MethodTreeNode.cs +++ b/ILSpy/TreeNodes/MethodTreeNode.cs @@ -41,6 +41,8 @@ public MethodTreeNode(IMethod method) public override object Text => GetText(GetMethodDefinition(), Language) + GetSuffixString(MethodDefinition); + public override object NavigationText => GetText(GetMethodDefinition(), Language, includeDeclaringTypeName: true); + private IMethod GetMethodDefinition() { return ((MetadataModule)MethodDefinition.ParentModule?.MetadataFile @@ -48,9 +50,9 @@ private IMethod GetMethodDefinition() ?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition; } - public static object GetText(IMethod method, Language language) + public static object GetText(IMethod method, Language language, bool includeDeclaringTypeName = false) { - return language.MethodToString(method, false, false, false); + return language.MethodToString(method, includeDeclaringTypeName, false, false); } public override object Icon => GetIcon(GetMethodDefinition()); diff --git a/ILSpy/TreeNodes/PropertyTreeNode.cs b/ILSpy/TreeNodes/PropertyTreeNode.cs index 12d689d186..255299f8c7 100644 --- a/ILSpy/TreeNodes/PropertyTreeNode.cs +++ b/ILSpy/TreeNodes/PropertyTreeNode.cs @@ -51,6 +51,8 @@ public PropertyTreeNode(IProperty property) public override object Text => GetText(GetPropertyDefinition(), Language) + GetSuffixString(PropertyDefinition); + public override object NavigationText => GetText(GetPropertyDefinition(), Language, includeDeclaringTypeName: true); + private IProperty GetPropertyDefinition() { return ((MetadataModule)PropertyDefinition.ParentModule?.MetadataFile @@ -58,9 +60,9 @@ private IProperty GetPropertyDefinition() ?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition; } - public static object GetText(IProperty property, Language language) + public static object GetText(IProperty property, Language language, bool includeDeclaringTypeName = false) { - return language.PropertyToString(property, false, false, false); + return language.PropertyToString(property, includeDeclaringTypeName, false, false); } public override object Icon => GetIcon(GetPropertyDefinition()); diff --git a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs index 6957ea6344..2503c6ad3d 100644 --- a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs +++ b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs @@ -44,6 +44,8 @@ public ReferenceFolderTreeNode(MetadataFile module, AssemblyTreeNode parentAssem public override object Text => Resources.References; + public override object NavigationText => module.Name + " " + Text; + public override object Icon => Images.ReferenceFolder; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/ResourceListTreeNode.cs b/ILSpy/TreeNodes/ResourceListTreeNode.cs index 9ce35eaf70..f461cf906d 100644 --- a/ILSpy/TreeNodes/ResourceListTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceListTreeNode.cs @@ -41,6 +41,8 @@ public ResourceListTreeNode(MetadataFile module) public override object Text => Resources._Resources; + public override object NavigationText => module.Name + " " + Text; + public override object Icon => Images.FolderClosed; public override object ExpandedIcon => Images.FolderOpen; diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index d2e7bdc31c..343f8f3dfe 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -45,6 +45,9 @@ public TypeTreeNode(ITypeDefinition typeDefinition, AssemblyTreeNode parentAssem public override object Text => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: false) + GetSuffixString(TypeDefinition.MetadataToken); + public override object NavigationText => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: true) + + GetSuffixString(TypeDefinition.MetadataToken); + private ITypeDefinition GetTypeDefinition() { return ((MetadataModule)ParentAssemblyNode.LoadedAssembly From 74f4fdba69d830a7754c1a42949d950a8217affd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 10:14:55 +0100 Subject: [PATCH 2/7] fixing whitespace --- ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs | 3 +-- ILSpy/AssemblyTree/AssemblyTreeModel.cs | 14 +++++++------- ILSpy/Controls/MainToolBar.xaml.cs | 4 ++-- ILSpy/Metadata/MetadataTreeNode.cs | 2 +- ILSpy/NavigationState.cs | 6 ++---- ILSpy/TreeNodes/FieldTreeNode.cs | 2 +- ILSpy/TreeNodes/ReferenceFolderTreeNode.cs | 2 +- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs index 7a735070c9..412d4f5221 100644 --- a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs +++ b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs @@ -126,8 +126,7 @@ public virtual object? Text { get { return null; } } - public virtual object? NavigationText - { + public virtual object? NavigationText { get { return Text; } } diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index 8a0a390ed9..d34d6a991a 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -857,10 +857,10 @@ public void NavigateHistory(bool forward, NavigationState? toState = null) { try { - TabPageModel tabPage = DockWorkspace.ActiveTabPage; - var currentState = tabPage.GetState(); - if (currentState != null) - history.UpdateCurrent(new NavigationState(tabPage, currentState)); + TabPageModel tabPage = DockWorkspace.ActiveTabPage; + var currentState = tabPage.GetState(); + if (currentState != null) + history.UpdateCurrent(new NavigationState(tabPage, currentState)); NavigationState newState; do @@ -868,8 +868,8 @@ public void NavigateHistory(bool forward, NavigationState? toState = null) newState = forward ? history.GoForward() : history.GoBack(); } while (newState != null && toState != null && toState != newState); - if (newState == null) - return; + if (newState == null) + return; navigatingToState = newState; @@ -893,7 +893,7 @@ public void NavigateHistory(bool forward, NavigationState? toState = null) } } - public NavigationState[] GetNavigateHistory(bool forward) => forward ? history.ForwardList : history.BackList; + public NavigationState[] GetNavigateHistory(bool forward) => forward ? history.ForwardList : history.BackList; public bool CanNavigateBack => history.CanNavigateBack; diff --git a/ILSpy/Controls/MainToolBar.xaml.cs b/ILSpy/Controls/MainToolBar.xaml.cs index 52f66a0df3..877796e967 100644 --- a/ILSpy/Controls/MainToolBar.xaml.cs +++ b/ILSpy/Controls/MainToolBar.xaml.cs @@ -117,7 +117,7 @@ static UIElement CreateToolbarItem(IExport co var dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal }; - var contextMenu = new ContextMenu { + var contextMenu = new ContextMenu { PlacementTarget = dropDownPanel, Tag = command }; @@ -144,7 +144,7 @@ static UIElement CreateToolbarItem(IExport co BindingOperations.SetBinding(dropDownToggle, ToggleButton.IsCheckedProperty, new Binding(nameof(contextMenu.IsOpen)) { Source = contextMenu }); - BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty, + BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty, new Binding(nameof(IsEnabled)) { Source = toolbarItem }); dropDownPanel.Children.Add(toolbarItem); diff --git a/ILSpy/Metadata/MetadataTreeNode.cs b/ILSpy/Metadata/MetadataTreeNode.cs index ac386c9436..a56856254e 100644 --- a/ILSpy/Metadata/MetadataTreeNode.cs +++ b/ILSpy/Metadata/MetadataTreeNode.cs @@ -46,7 +46,7 @@ public MetadataTreeNode(MetadataFile module, string title) public override object Text => title; public override object NavigationText => metadataFile.Name + " " + Text; - + public override object Icon => Images.Metadata; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/NavigationState.cs b/ILSpy/NavigationState.cs index dbd5545e26..7e7151fa0a 100644 --- a/ILSpy/NavigationState.cs +++ b/ILSpy/NavigationState.cs @@ -64,10 +64,8 @@ public bool Equals(NavigationState other) return this.ViewState.Equals(other.ViewState); } - public object NavigationText - { - get - { + public object NavigationText { + get { if (this.treeNodes.Count == 1) return this.treeNodes.First(); diff --git a/ILSpy/TreeNodes/FieldTreeNode.cs b/ILSpy/TreeNodes/FieldTreeNode.cs index 1cf4b17b20..5bf508aaf3 100644 --- a/ILSpy/TreeNodes/FieldTreeNode.cs +++ b/ILSpy/TreeNodes/FieldTreeNode.cs @@ -41,7 +41,7 @@ public FieldTreeNode(IField field) public override object Text => GetText(GetFieldDefinition(), Language) + GetSuffixString(FieldDefinition); - public override object NavigationText => GetText(GetFieldDefinition(), Language, includeDeclaringTypeName: true); + public override object NavigationText => GetText(GetFieldDefinition(), Language, includeDeclaringTypeName: true); private IField GetFieldDefinition() { diff --git a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs index 2503c6ad3d..b449801a6e 100644 --- a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs +++ b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs @@ -45,7 +45,7 @@ public ReferenceFolderTreeNode(MetadataFile module, AssemblyTreeNode parentAssem public override object Text => Resources.References; public override object NavigationText => module.Name + " " + Text; - + public override object Icon => Images.ReferenceFolder; protected override void LoadChildren() From 6b91fc3f33893d803798481e5b64ebfae6e3a82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 11:19:09 +0100 Subject: [PATCH 3/7] Workaround for dismissing navigation menu --- ILSpy/Controls/MainToolBar.xaml.cs | 33 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/ILSpy/Controls/MainToolBar.xaml.cs b/ILSpy/Controls/MainToolBar.xaml.cs index 877796e967..4cf45a4193 100644 --- a/ILSpy/Controls/MainToolBar.xaml.cs +++ b/ILSpy/Controls/MainToolBar.xaml.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.ComponentModel; using System.Composition; using System.Linq; using System.Windows; @@ -117,6 +119,14 @@ static UIElement CreateToolbarItem(IExport co var dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal }; + var dropDownToggle = new ToggleButton { + Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(), + Content = "▾", + Padding = new Thickness(0), + MinWidth = 0, + Margin = new Thickness(0, 0, 2, 0) + }; + var contextMenu = new ContextMenu { PlacementTarget = dropDownPanel, Tag = command @@ -126,15 +136,6 @@ static UIElement CreateToolbarItem(IExport co toolbarItem.ContextMenu = contextMenu; toolbarItem.ContextMenuOpening += (_, _) => PrepareParameterList(contextMenu); - - var dropDownToggle = new ToggleButton { - Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(), - Content = "▾", - Padding = new Thickness(0), - MinWidth = 0, - Margin = new Thickness(0, 0, 2, 0) - }; - dropDownToggle.Checked += (_, _) => { PrepareParameterList(contextMenu); contextMenu.Placement = PlacementMode.Bottom; @@ -147,6 +148,20 @@ static UIElement CreateToolbarItem(IExport co BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty, new Binding(nameof(IsEnabled)) { Source = toolbarItem }); + // When the toggle button is checked, clicking it to uncheck will dimiss the menu first + // which unchecks the toggle button via binding above and the click is used to open it again. + // This is a workaround to ignore the click to uncheck the already unchecked toggle button. + // We have to ensure the dismissing click is on the toggle button, otherwise the flag + // will not get cleared and menu will not open next time. + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(contextMenu, (_, e) => { + var point = e.GetPosition(dropDownToggle); + dropDownToggle.Tag = dropDownToggle.InputHitTest(point); + }); + dropDownToggle.PreviewMouseLeftButtonDown += (_, e) => { + e.Handled = dropDownToggle.Tag != null; + dropDownToggle.Tag = null; + }; + dropDownPanel.Children.Add(toolbarItem); dropDownPanel.Children.Add(dropDownToggle); return dropDownPanel; From ab2ff5aebe46ed38e8782a41cc0f9828326efcc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 11:27:50 +0100 Subject: [PATCH 4/7] Navigation menu folders formatting --- ILSpy/Metadata/MetadataTreeNode.cs | 2 +- ILSpy/TreeNodes/BaseTypesTreeNode.cs | 2 +- ILSpy/TreeNodes/DerivedTypesTreeNode.cs | 2 +- ILSpy/TreeNodes/ReferenceFolderTreeNode.cs | 2 +- ILSpy/TreeNodes/ResourceListTreeNode.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ILSpy/Metadata/MetadataTreeNode.cs b/ILSpy/Metadata/MetadataTreeNode.cs index a56856254e..b82a38eb13 100644 --- a/ILSpy/Metadata/MetadataTreeNode.cs +++ b/ILSpy/Metadata/MetadataTreeNode.cs @@ -45,7 +45,7 @@ public MetadataTreeNode(MetadataFile module, string title) public override object Text => title; - public override object NavigationText => metadataFile.Name + " " + Text; + public override object NavigationText => $"{Text} ({metadataFile.Name})"; public override object Icon => Images.Metadata; diff --git a/ILSpy/TreeNodes/BaseTypesTreeNode.cs b/ILSpy/TreeNodes/BaseTypesTreeNode.cs index f0726b4321..d19184ffa8 100644 --- a/ILSpy/TreeNodes/BaseTypesTreeNode.cs +++ b/ILSpy/TreeNodes/BaseTypesTreeNode.cs @@ -46,7 +46,7 @@ public BaseTypesTreeNode(MetadataFile module, ITypeDefinition type) public override object Text => Properties.Resources.BaseTypes; - public override object NavigationText => this.Language.TypeToString(type, includeNamespace: true) + " " + Text; + public override object NavigationText => $"{Text} ({this.Language.TypeToString(type, includeNamespace: true)})"; public override object Icon => Images.SuperTypes; diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 5166f0758d..8e67a171ee 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -47,7 +47,7 @@ public DerivedTypesTreeNode(AssemblyList list, ITypeDefinition type) public override object Text => Resources.DerivedTypes; - public override object NavigationText => this.Language.TypeToString(type, includeNamespace: true) + " " + Text; + public override object NavigationText => $"{Text} ({this.Language.TypeToString(type, includeNamespace: true)})"; public override object Icon => Images.SubTypes; diff --git a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs index b449801a6e..87e72296db 100644 --- a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs +++ b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs @@ -44,7 +44,7 @@ public ReferenceFolderTreeNode(MetadataFile module, AssemblyTreeNode parentAssem public override object Text => Resources.References; - public override object NavigationText => module.Name + " " + Text; + public override object NavigationText => $"{Text} ({module.Name})"; public override object Icon => Images.ReferenceFolder; diff --git a/ILSpy/TreeNodes/ResourceListTreeNode.cs b/ILSpy/TreeNodes/ResourceListTreeNode.cs index f461cf906d..1746528176 100644 --- a/ILSpy/TreeNodes/ResourceListTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceListTreeNode.cs @@ -41,7 +41,7 @@ public ResourceListTreeNode(MetadataFile module) public override object Text => Resources._Resources; - public override object NavigationText => module.Name + " " + Text; + public override object NavigationText => $"{Text} ({module.Name})"; public override object Icon => Images.FolderClosed; From 6a10b333055093f646c6136ebd870d76449043d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 12:08:56 +0100 Subject: [PATCH 5/7] NavigationText for more nodes --- ILSpy/Properties/Resources.Designer.cs | 11 ++++++++++- ILSpy/Properties/Resources.resx | 3 +++ .../AssemblyReferenceReferencedTypesTreeNode.cs | 2 +- ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs | 2 ++ ILSpy/TreeNodes/BaseTypesEntryNode.cs | 2 ++ ILSpy/TreeNodes/DerivedTypesEntryNode.cs | 2 ++ ILSpy/TreeNodes/MemberReferenceTreeNode.cs | 2 ++ ILSpy/TreeNodes/ModuleReferenceTreeNode.cs | 2 ++ ILSpy/TreeNodes/TypeReferenceTreeNode.cs | 2 ++ 9 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs index 3ddca0ae23..1443740985 100644 --- a/ILSpy/Properties/Resources.Designer.cs +++ b/ILSpy/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ICSharpCode.ILSpy.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { @@ -2357,6 +2357,15 @@ public static string R_ename { } } + /// + /// Looks up a localized string similar to Referenced Types. + /// + public static string ReferencedTypes { + get { + return ResourceManager.GetString("ReferencedTypes", resourceCulture); + } + } + /// /// Looks up a localized string similar to Reference Name. /// diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx index ee03a43251..b8d9d7cbcc 100644 --- a/ILSpy/Properties/Resources.resx +++ b/ILSpy/Properties/Resources.resx @@ -809,6 +809,9 @@ If this does not solve the problem and your system supports long paths, you can Reference Name + + Referenced Types + References diff --git a/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs index 3f811a0edc..edc4411889 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs @@ -40,7 +40,7 @@ public AssemblyReferenceReferencedTypesTreeNode(MetadataModule module, AssemblyR this.LazyLoading = true; } - public override object Text => $"Referenced Types ({r.TypeReferences.Length + r.ExportedTypes.Length})"; + public override object Text => $"{Properties.Resources.ReferencedTypes} ({r.TypeReferences.Length + r.ExportedTypes.Length})"; public override object Icon => Images.MetadataTable; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs index 7eeae132cb..b83e885afe 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs @@ -53,6 +53,8 @@ public override object Text { get { return Language.EscapeName(r.Name) + GetSuffixString(r.Handle); } } + public override object NavigationText => $"{Text} ({Properties.Resources.References})"; + public override object Icon => ImagesProvider.Assembly; public override bool ShowExpander { diff --git a/ILSpy/TreeNodes/BaseTypesEntryNode.cs b/ILSpy/TreeNodes/BaseTypesEntryNode.cs index 0c1f68b33a..7d6168aff5 100644 --- a/ILSpy/TreeNodes/BaseTypesEntryNode.cs +++ b/ILSpy/TreeNodes/BaseTypesEntryNode.cs @@ -36,6 +36,8 @@ public BaseTypesEntryNode(ITypeDefinition type) public override object Text => this.Language.TypeToString(type, includeNamespace: true); + public override object NavigationText => $"{Text} ({Properties.Resources.BaseTypes})"; + public override object Icon => type.Kind == TypeKind.Interface ? Images.Interface : Images.Class; public override void ActivateItem(IPlatformRoutedEventArgs e) diff --git a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs index ac068f24c4..8b3fac2333 100644 --- a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs @@ -47,6 +47,8 @@ public override object Text { get { return Language.TypeToString(type, includeNamespace: true) + GetSuffixString(type.MetadataToken); } } + public override object NavigationText => $"{Text} ({Properties.Resources.DerivedTypes})"; + public override object Icon => TypeTreeNode.GetIcon(type); public override FilterResult Filter(LanguageSettings settings) diff --git a/ILSpy/TreeNodes/MemberReferenceTreeNode.cs b/ILSpy/TreeNodes/MemberReferenceTreeNode.cs index fedf9b5a05..4d4598a8d3 100644 --- a/ILSpy/TreeNodes/MemberReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/MemberReferenceTreeNode.cs @@ -49,6 +49,8 @@ public MemberReferenceTreeNode(MetadataModule module, MemberReferenceMetadata r) public override object Text => Signature + GetSuffixString(r.Handle); + public override object NavigationText => $"{Text} ({Properties.Resources.ReferencedTypes})"; + public override object Icon => r.MemberReferenceKind switch { MemberReferenceKind.Method => Images.MethodReference, MemberReferenceKind.Field => Images.FieldReference, diff --git a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs index c893007b8f..57e91cee8d 100644 --- a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs @@ -68,6 +68,8 @@ public override object Text { get { return moduleName + GetSuffixString(handle); } } + public override object NavigationText => $"{Text} ({Properties.Resources.References})"; + public override object Icon => Images.Library; public override void ActivateItem(IPlatformRoutedEventArgs e) diff --git a/ILSpy/TreeNodes/TypeReferenceTreeNode.cs b/ILSpy/TreeNodes/TypeReferenceTreeNode.cs index 431ab57dac..6a47c47675 100644 --- a/ILSpy/TreeNodes/TypeReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/TypeReferenceTreeNode.cs @@ -45,6 +45,8 @@ public TypeReferenceTreeNode(MetadataModule module, TypeReferenceMetadata r) public override object Text => Language.TypeToString(resolvedType, includeNamespace: false) + GetSuffixString(r.Handle); + public override object NavigationText => $"{Text} ({Properties.Resources.ReferencedTypes})"; + public override object Icon => Images.TypeReference; protected override void LoadChildren() From af73e85f9566a92264ac5ea8018dcb439f23b35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 14:16:58 +0100 Subject: [PATCH 6/7] Navigation list forward sort order --- ILSpy/Commands/BrowseForwardCommand.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ILSpy/Commands/BrowseForwardCommand.cs b/ILSpy/Commands/BrowseForwardCommand.cs index 74b42a1cd1..919ecdea03 100644 --- a/ILSpy/Commands/BrowseForwardCommand.cs +++ b/ILSpy/Commands/BrowseForwardCommand.cs @@ -18,6 +18,7 @@ using System.Collections; using System.Composition; +using System.Linq; using System.Windows.Input; using ICSharpCode.ILSpy.AssemblyTree; @@ -54,7 +55,7 @@ protected override void OnExecute(object sender, ExecutedRoutedEventArgs e) } } - public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(true); + public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(true).Reverse(); public object GetParamaterText(object parameter) { From 7f75589319c904fe6e3bf826e7f88614cfbe6d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 14:17:23 +0100 Subject: [PATCH 7/7] NavigationText for metadata nodes --- ICSharpCode.Decompiler/Metadata/MetadataFile.cs | 9 ++++++--- ILSpy/Metadata/CoffHeaderTreeNode.cs | 2 ++ ILSpy/Metadata/DataDirectoriesTreeNode.cs | 2 ++ .../DebugDirectory/DebugDirectoryEntryTreeNode.cs | 2 ++ ILSpy/Metadata/DebugDirectoryTreeNode.cs | 2 ++ ILSpy/Metadata/DebugMetadataTablesTreeNode.cs | 2 ++ ILSpy/Metadata/DosHeaderTreeNode.cs | 2 ++ ILSpy/Metadata/MetadataHeapTreeNode.cs | 2 ++ ILSpy/Metadata/MetadataTableTreeNode.cs | 2 ++ ILSpy/Metadata/MetadataTablesTreeNode.cs | 2 ++ ILSpy/Metadata/OptionalHeaderTreeNode.cs | 2 ++ 11 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler/Metadata/MetadataFile.cs b/ICSharpCode.Decompiler/Metadata/MetadataFile.cs index ac0c1da1f5..0e00052d63 100644 --- a/ICSharpCode.Decompiler/Metadata/MetadataFile.cs +++ b/ICSharpCode.Decompiler/Metadata/MetadataFile.cs @@ -73,9 +73,12 @@ public string Name { if (value == null) { var metadata = Metadata; - value = metadata.IsAssembly - ? metadata.GetString(metadata.GetAssemblyDefinition().Name) - : metadata.GetString(metadata.GetModuleDefinition().Name); + if (metadata.IsAssembly) + value = metadata.GetString(metadata.GetAssemblyDefinition().Name); + else if (metadata.DebugMetadataHeader == null) // standalone debug metadata does not contain module table + value = metadata.GetString(metadata.GetModuleDefinition().Name); + else + value = "debug metadata"; value = LazyInit.GetOrSet(ref name, value); } return value; diff --git a/ILSpy/Metadata/CoffHeaderTreeNode.cs b/ILSpy/Metadata/CoffHeaderTreeNode.cs index 71a4a491ac..20b46050f8 100644 --- a/ILSpy/Metadata/CoffHeaderTreeNode.cs +++ b/ILSpy/Metadata/CoffHeaderTreeNode.cs @@ -43,6 +43,8 @@ public CoffHeaderTreeNode(PEFile module) public override object Text => "COFF Header"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.Header; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/Metadata/DataDirectoriesTreeNode.cs b/ILSpy/Metadata/DataDirectoriesTreeNode.cs index c54fa9b2cf..0b5d4f31c0 100644 --- a/ILSpy/Metadata/DataDirectoriesTreeNode.cs +++ b/ILSpy/Metadata/DataDirectoriesTreeNode.cs @@ -35,6 +35,8 @@ public DataDirectoriesTreeNode(PEFile module) public override object Text => "Data Directories"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.ListFolder; public override object ExpandedIcon => Images.ListFolderOpen; diff --git a/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs b/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs index da233ca388..6326a8660a 100644 --- a/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs +++ b/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs @@ -40,6 +40,8 @@ public DebugDirectoryEntryTreeNode(PEFile module, DebugDirectoryEntry entry) override public object Text => entry.Type.ToString(); + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.MetadataTable; public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) diff --git a/ILSpy/Metadata/DebugDirectoryTreeNode.cs b/ILSpy/Metadata/DebugDirectoryTreeNode.cs index ceaa6cf3e1..37f6f7e89c 100644 --- a/ILSpy/Metadata/DebugDirectoryTreeNode.cs +++ b/ILSpy/Metadata/DebugDirectoryTreeNode.cs @@ -40,6 +40,8 @@ public DebugDirectoryTreeNode(PEFile module) public override object Text => "Debug Directory"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.ListFolder; public override object ExpandedIcon => Images.ListFolderOpen; diff --git a/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs b/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs index 5ce76eaa6f..8131f0910b 100644 --- a/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs +++ b/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs @@ -37,6 +37,8 @@ public DebugMetadataTablesTreeNode(MetadataFile metadataFile) public override object Text => "Tables"; + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.MetadataTableGroup; protected override void LoadChildren() diff --git a/ILSpy/Metadata/DosHeaderTreeNode.cs b/ILSpy/Metadata/DosHeaderTreeNode.cs index 59845ea8d7..1deec97175 100644 --- a/ILSpy/Metadata/DosHeaderTreeNode.cs +++ b/ILSpy/Metadata/DosHeaderTreeNode.cs @@ -36,6 +36,8 @@ public DosHeaderTreeNode(PEFile module) public override object Text => "DOS Header"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.Header; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/Metadata/MetadataHeapTreeNode.cs b/ILSpy/Metadata/MetadataHeapTreeNode.cs index 2c0ee3c791..a74ccd6478 100644 --- a/ILSpy/Metadata/MetadataHeapTreeNode.cs +++ b/ILSpy/Metadata/MetadataHeapTreeNode.cs @@ -33,6 +33,8 @@ internal abstract class MetadataHeapTreeNode : ILSpyTreeNode public HandleKind Kind { get; } + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.Heap; public MetadataHeapTreeNode(HandleKind kind, MetadataFile metadataFile) diff --git a/ILSpy/Metadata/MetadataTableTreeNode.cs b/ILSpy/Metadata/MetadataTableTreeNode.cs index e826bdc46c..ccc13c60de 100644 --- a/ILSpy/Metadata/MetadataTableTreeNode.cs +++ b/ILSpy/Metadata/MetadataTableTreeNode.cs @@ -39,6 +39,8 @@ internal abstract class MetadataTableTreeNode : ILSpyTreeNode public override object Text => $"{(int)Kind:X2} {Kind} ({metadataFile.Metadata.GetTableRowCount(Kind)})"; + public override object NavigationText => $"{(int)Kind:X2} {Kind} ({metadataFile.Name})"; + public override object Icon => Images.MetadataTable; public MetadataTableTreeNode(TableIndex table, MetadataFile metadataFile) diff --git a/ILSpy/Metadata/MetadataTablesTreeNode.cs b/ILSpy/Metadata/MetadataTablesTreeNode.cs index e7a1ae934a..f00894e4b4 100644 --- a/ILSpy/Metadata/MetadataTablesTreeNode.cs +++ b/ILSpy/Metadata/MetadataTablesTreeNode.cs @@ -39,6 +39,8 @@ public MetadataTablesTreeNode(MetadataFile metadataFile) public override object Text => "Tables"; + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.MetadataTableGroup; protected override void LoadChildren() diff --git a/ILSpy/Metadata/OptionalHeaderTreeNode.cs b/ILSpy/Metadata/OptionalHeaderTreeNode.cs index aa7cf2e7ab..7ad743f356 100644 --- a/ILSpy/Metadata/OptionalHeaderTreeNode.cs +++ b/ILSpy/Metadata/OptionalHeaderTreeNode.cs @@ -42,6 +42,8 @@ public OptionalHeaderTreeNode(PEFile module) public override object Text => "Optional Header"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.Header; public override bool View(ViewModels.TabPageModel tabPage)