Browse Source

Decouple AssemblyListPane from MainWindow

pull/3274/head
tom-englert 9 months ago committed by tom-englert
parent
commit
0c1c5cecd7
  1. 5
      ICSharpCode.ILSpyX/AssemblyList.cs
  2. 4
      ILSpy/Analyzers/AnalyzeCommand.cs
  3. 3
      ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
  4. 1
      ILSpy/Analyzers/AnalyzerRootNode.cs
  5. 2
      ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
  6. 1
      ILSpy/Analyzers/AnalyzerTreeNode.cs
  7. 2
      ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
  8. 54
      ILSpy/AssemblyTree/AssemblyListPane.xaml
  9. 44
      ILSpy/AssemblyTree/AssemblyListPane.xaml.cs
  10. 896
      ILSpy/AssemblyTree/AssemblyListPaneModel.cs
  11. 5
      ILSpy/Commands/DecompileAllCommand.cs
  12. 2
      ILSpy/Commands/DecompileCommand.cs
  13. 17
      ILSpy/Commands/DecompileInNewViewCommand.cs
  14. 2
      ILSpy/Commands/DisassembleAllCommand.cs
  15. 6
      ILSpy/Commands/GeneratePdbContextMenuEntry.cs
  16. 4
      ILSpy/Commands/Pdb2XmlCommand.cs
  17. 10
      ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs
  18. 1
      ILSpy/Commands/SaveCodeContextMenuEntry.cs
  19. 6
      ILSpy/Commands/SelectPdbContextMenuEntry.cs
  20. 3
      ILSpy/Commands/SetThemeCommand.cs
  21. 1
      ILSpy/Commands/ShowCFGContextMenuEntry.cs
  22. 23
      ILSpy/Commands/SortAssemblyListCommand.cs
  23. 33
      ILSpy/ContextMenuEntry.cs
  24. 1
      ILSpy/Controls/TreeView/SharpTreeView.cs
  25. 6
      ILSpy/Docking/DockWorkspace.cs
  26. 1
      ILSpy/ExtensionMethods.cs
  27. 1
      ILSpy/GlobalUsings.cs
  28. 1
      ILSpy/LanguageSettings.cs
  29. 1
      ILSpy/Languages/CSharpILMixedLanguage.cs
  30. 7
      ILSpy/Languages/CSharpLanguage.cs
  31. 1
      ILSpy/Languages/ILLanguage.cs
  32. 46
      ILSpy/MainWindow.xaml
  33. 820
      ILSpy/MainWindow.xaml.cs
  34. 2
      ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs
  35. 2
      ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs
  36. 4
      ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs
  37. 2
      ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs
  38. 4
      ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs
  39. 2
      ILSpy/Metadata/CorTables/EventTableTreeNode.cs
  40. 2
      ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs
  41. 2
      ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs
  42. 2
      ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs
  43. 2
      ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs
  44. 4
      ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs
  45. 2
      ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs
  46. 4
      ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs
  47. 4
      ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs
  48. 2
      ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs
  49. 2
      ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs
  50. 6
      ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs
  51. 4
      ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs
  52. 2
      ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs
  53. 2
      ILSpy/Metadata/CorTables/MethodTableTreeNode.cs
  54. 4
      ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs
  55. 4
      ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs
  56. 6
      ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs
  57. 2
      ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs
  58. 1
      ILSpy/Metadata/DebugMetadataTablesTreeNode.cs
  59. 2
      ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs
  60. 2
      ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs
  61. 8
      ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs
  62. 4
      ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs
  63. 4
      ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs
  64. 2
      ILSpy/Metadata/GoToTokenCommand.cs
  65. 2
      ILSpy/Metadata/MetadataProtocolHandler.cs
  66. 1
      ILSpy/Metadata/MetadataTablesTreeNode.cs
  67. 1
      ILSpy/Options/DecompilerSettingsPanel.xaml.cs
  68. 1
      ILSpy/Options/DisplaySettingsPanel.xaml.cs
  69. 7
      ILSpy/Search/SearchPane.xaml.cs
  70. 1
      ILSpy/Search/SearchPaneModel.cs
  71. 1
      ILSpy/SessionSettings.cs
  72. 2
      ILSpy/TaskHelper.cs
  73. 8
      ILSpy/TextView/DecompilerTextView.cs
  74. 5
      ILSpy/TextView/DocumentationUIBuilder.cs
  75. 1
      ILSpy/Themes/WindowStyleManagerBehavior.cs
  76. 18
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  77. 1
      ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
  78. 12
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  79. 5
      ILSpy/TreeNodes/ILSpyTreeNode.cs
  80. 9
      ILSpy/Util/MessageBus.cs
  81. 48
      ILSpy/Util/NavigationHistoryService.cs
  82. 41
      ILSpy/ViewModels/AssemblyListPaneModel.cs
  83. 1
      ILSpy/ViewModels/ManageAssemblyListsViewModel.cs
  84. 14
      ILSpy/ViewModels/PaneModel.cs
  85. 2
      ILSpy/ViewModels/TabPageModel.cs
  86. 9
      ILSpy/Views/DebugSteps.xaml.cs
  87. 2
      TestPlugin/MainMenuCommand.cs

5
ICSharpCode.ILSpyX/AssemblyList.cs

@ -281,8 +281,9 @@ namespace ICSharpCode.ILSpyX @@ -281,8 +281,9 @@ namespace ICSharpCode.ILSpyX
{
file = Path.GetFullPath(file);
return OpenAssembly(file, () => {
var newAsm = new LoadedAssembly(this, file, fileLoaders: manager?.LoaderRegistry, applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);
newAsm.IsAutoLoaded = isAutoLoaded;
var newAsm = new LoadedAssembly(this, file, fileLoaders: manager?.LoaderRegistry, applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols) {
IsAutoLoaded = isAutoLoaded
};
return newAsm;
});
}

4
ILSpy/Analyzers/AnalyzeCommand.cs

@ -78,12 +78,12 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -78,12 +78,12 @@ namespace ICSharpCode.ILSpy.Analyzers
public override bool CanExecute(object parameter)
{
return MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode);
return MainWindow.Instance.AssemblyTreeModel.SelectedNodes.All(n => n is IMemberTreeNode);
}
public override void Execute(object parameter)
{
foreach (var node in MainWindow.Instance.SelectedNodes.OfType<IMemberTreeNode>())
foreach (var node in MainWindow.Instance.AssemblyTreeModel.SelectedNodes.OfType<IMemberTreeNode>())
{
AnalyzerTreeView.Analyze(node.Member);
}

3
ILSpy/Analyzers/AnalyzerEntityTreeNode.cs

@ -42,7 +42,8 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -42,7 +42,8 @@ namespace ICSharpCode.ILSpy.Analyzers
MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy");
return;
}
MainWindow.Instance.JumpToReference(new EntityReference(this.Member.ParentModule.MetadataFile, this.Member.MetadataToken));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(this.Member.ParentModule?.MetadataFile, this.Member.MetadataToken)));
}
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)

1
ILSpy/Analyzers/AnalyzerRootNode.cs

@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
using System.Collections.Specialized;
using System.Linq;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView;

2
ILSpy/Analyzers/AnalyzerSearchTreeNode.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.Analyzers
var context = new AnalyzerContext() {
CancellationToken = ct,
Language = Language,
AssemblyList = MainWindow.Instance.CurrentAssemblyList
AssemblyList = MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList
};
var results = analyzer.Analyze(symbol, context).Select(SymbolTreeNodeFactory);
if (context.SortResults)

1
ILSpy/Analyzers/AnalyzerTreeNode.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System.Collections.Generic;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView;

2
ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy");
return;
}
MainWindow.Instance.JumpToReference(analyzedModule.MetadataFile);
MessageBus.Send(this, new NavigateToReferenceEventArgs(analyzedModule.MetadataFile));
}
public override IEntity Member => null;

54
ILSpy/AssemblyTree/AssemblyListPane.xaml

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
<treeView:SharpTreeView x:Class="ICSharpCode.ILSpy.AssemblyTree.AssemblyListPane"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:treeView="clr-namespace:ICSharpCode.ILSpy.Controls.TreeView"
xmlns:treeNodes="clr-namespace:ICSharpCode.ILSpy.TreeNodes"
xmlns:assemblyTree="clr-namespace:ICSharpCode.ILSpy.AssemblyTree"
xmlns:toms="urn:TomsToolbox"
mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance assemblyTree:AssemblyListPaneModel}"
AutomationProperties.Name="Assemblies and Classes"
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0" Visibility="Visible"
Root="{Binding Root}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
toms:MultiSelectorExtensions.SelectionBinding="{Binding SelectedItems}">
<treeView:SharpTreeView.ItemContainerStyle>
<Style TargetType="treeView:SharpTreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type treeView:SharpTreeViewItem}"
d:DataContext="{d:DesignInstance treeNodes:ILSpyTreeNode}">
<Border Background="Transparent">
<Border Background="{TemplateBinding Background}">
<treeView:SharpTreeNodeView x:Name="nodeView" HorizontalAlignment="Left" />
</Border>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsAutoLoaded}" Value="True">
<Setter Property="Foreground" Value="SteelBlue" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPublicAPI}" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</DataTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="nodeView" Property="TextBackground"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter TargetName="nodeView" Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="nodeView" Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</treeView:SharpTreeView.ItemContainerStyle>
</treeView:SharpTreeView>

44
ILSpy/AssemblyTree/AssemblyListPane.xaml.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
using System.ComponentModel.Composition;
using System.Windows;
using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Wpf.Composition.Mef;
namespace ICSharpCode.ILSpy.AssemblyTree
{
/// <summary>
/// Interaction logic for AssemblyListPane.xaml
/// </summary>
[DataTemplate(typeof(AssemblyListPaneModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class AssemblyListPane
{
public AssemblyListPane()
{
InitializeComponent();
ContextMenuProvider.Add(this);
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == DataContextProperty)
{
if (e.NewValue is not AssemblyListPaneModel model)
return;
model.SetActiveView(this);
}
else if (e.Property == SelectedItemProperty)
{
if (e.NewValue is not SharpTreeNode treeNode)
return;
FocusNode(treeNode);
}
}
}
}

896
ILSpy/AssemblyTree/AssemblyListPaneModel.cs

@ -0,0 +1,896 @@ @@ -0,0 +1,896 @@
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Settings;
using ICSharpCode.ILSpyX.TreeView;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Windows;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using System.Reflection.Metadata;
using ICSharpCode.ILSpyX.Extensions;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.Decompiler;
using System.Text;
using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy.AssemblyTree
{
[ExportToolPane]
[PartCreationPolicy(CreationPolicy.Shared)]
[Export]
public class AssemblyListPaneModel : ToolPaneModel
{
public const string PaneContentId = "assemblyListPane";
AssemblyListPane activeView;
AssemblyList assemblyList;
AssemblyListTreeNode assemblyListTreeNode;
bool refreshInProgress;
bool changingActiveTab;
readonly NavigationHistoryService history = NavigationHistoryService.Instance;
public AssemblyListPaneModel()
{
Title = Resources.Assemblies;
ContentId = PaneContentId;
IsCloseable = false;
ShortcutKey = new KeyGesture(Key.F6);
MessageBus<NavigateToReferenceEventArgs>.Subscribers += JumpToReference;
MessageBus<SessionSettingsChangedEventArgs>.Subscribers += (sender, e) => SessionSettings_PropertyChanged(sender, e);
MessageBus<LanguageSettingsChangedEventArgs>.Subscribers += (sender, e) => LanguageSettings_PropertyChanged(sender, e);
var selectionChangeThrottle = new DispatcherThrottle(DispatcherPriority.Background, TreeView_SelectionChanged);
SelectedItems.CollectionChanged += (_, _) => selectionChangeThrottle.Tick();
}
private void SessionSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var sessionSettings = SettingsService.Instance.SessionSettings;
switch (e.PropertyName)
{
case nameof(SessionSettings.ActiveAssemblyList):
ShowAssemblyList(sessionSettings.ActiveAssemblyList);
break;
case nameof(SessionSettings.Theme):
// update syntax highlighting and force reload (AvalonEdit does not automatically refresh on highlighting change)
DecompilerTextView.RegisterHighlighting();
DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState);
break;
case nameof(SessionSettings.CurrentCulture):
MessageBox.Show(Properties.Resources.SettingsChangeRestartRequired, "ILSpy");
break;
}
}
public AssemblyList CurrentAssemblyList {
get { return assemblyList; }
}
private SharpTreeNode root;
public SharpTreeNode Root {
get => root;
set => SetProperty(ref root, value);
}
private SharpTreeNode selectedItem;
public SharpTreeNode SelectedItem {
get => selectedItem;
set => SetProperty(ref selectedItem, value);
}
public ObservableCollection<SharpTreeNode> SelectedItems { get; } = [];
public string[] SelectedPath => GetPathForNode(SelectedItem);
readonly List<LoadedAssembly> commandLineLoadedAssemblies = [];
public bool HandleCommandLineArguments(CommandLineArguments args)
{
LoadAssemblies(args.AssembliesToLoad, commandLineLoadedAssemblies, focusNode: false);
if (args.Language != null)
SettingsService.Instance.SessionSettings.LanguageSettings.Language = Languages.GetLanguage(args.Language);
return true;
}
/// <summary>
/// Called on startup or when passed arguments via WndProc from a second instance.
/// In the format case, spySettings is non-null; in the latter it is null.
/// </summary>
public void HandleCommandLineArgumentsAfterShowList(CommandLineArguments args, ILSpySettings spySettings = null)
{
var sessionSettings = SettingsService.Instance.SessionSettings;
var relevantAssemblies = commandLineLoadedAssemblies.ToList();
commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore
NavigateOnLaunch(args.NavigateTo, sessionSettings.ActiveTreeViewPath, spySettings, relevantAssemblies);
if (args.Search != null)
{
var searchPane = App.ExportProvider.GetExportedValue<SearchPaneModel>();
searchPane.SearchTerm = args.Search;
searchPane.Show();
}
}
public async void NavigateOnLaunch(string navigateTo, string[] activeTreeViewPath, ILSpySettings spySettings, List<LoadedAssembly> relevantAssemblies)
{
var initialSelection = SelectedItem;
if (navigateTo != null)
{
bool found = false;
if (navigateTo.StartsWith("N:", StringComparison.Ordinal))
{
string namespaceName = navigateTo.Substring(2);
foreach (LoadedAssembly asm in relevantAssemblies)
{
AssemblyTreeNode asmNode = assemblyListTreeNode.FindAssemblyNode(asm);
if (asmNode != null)
{
// FindNamespaceNode() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead.
await asm.GetMetadataFileAsync().Catch<Exception>(ex => { });
NamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName);
if (nsNode != null)
{
found = true;
if (SelectedItem == initialSelection)
{
SelectNode(nsNode);
}
break;
}
}
}
}
else if (navigateTo == "none")
{
// Don't navigate anywhere; start empty.
// Used by ILSpy VS addin, it'll send us the real location to navigate to via IPC.
found = true;
}
else
{
IEntity mr = await Task.Run(() => FindEntityInRelevantAssemblies(navigateTo, relevantAssemblies));
// Make sure we wait for assemblies being loaded...
// BeginInvoke in LoadedAssembly.LookupReferencedAssemblyInternal
await Dispatcher.InvokeAsync(delegate { }, DispatcherPriority.Normal);
if (mr != null && mr.ParentModule?.MetadataFile != null)
{
found = true;
if (SelectedItem == initialSelection)
{
await JumpToReferenceAsync(mr);
}
}
}
if (!found && SelectedItem == initialSelection)
{
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.Write($"Cannot find '{navigateTo}' in command line specified assemblies.");
DockWorkspace.Instance.ShowText(output);
}
}
else if (relevantAssemblies.Count == 1)
{
// NavigateTo == null and an assembly was given on the command-line:
// Select the newly loaded assembly
AssemblyTreeNode asmNode = assemblyListTreeNode.FindAssemblyNode(relevantAssemblies[0]);
if (asmNode != null && SelectedItem == initialSelection)
{
SelectNode(asmNode);
}
}
else if (spySettings != null)
{
SharpTreeNode node = null;
if (activeTreeViewPath?.Length > 0)
{
foreach (var asm in CurrentAssemblyList.GetAssemblies())
{
if (asm.FileName == activeTreeViewPath[0])
{
// FindNodeByPath() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead.
await asm.GetMetadataFileAsync().Catch<Exception>(ex => { });
}
}
node = FindNodeByPath(activeTreeViewPath, true);
}
if (SelectedItem == initialSelection)
{
if (node != null)
{
SelectNode(node);
// only if not showing the about page, perform the update check:
await MainWindow.Instance.ShowMessageIfUpdatesAvailableAsync(spySettings);
}
else
{
DockWorkspace.Instance.ActiveTabPage.ShowTextView(AboutPage.Display);
}
}
}
}
public static IEntity FindEntityInRelevantAssemblies(string navigateTo, IEnumerable<LoadedAssembly> relevantAssemblies)
{
ITypeReference typeRef;
IMemberReference memberRef = null;
if (navigateTo.StartsWith("T:", StringComparison.Ordinal))
{
typeRef = IdStringProvider.ParseTypeName(navigateTo);
}
else
{
memberRef = IdStringProvider.ParseMemberIdString(navigateTo);
typeRef = memberRef.DeclaringTypeReference;
}
foreach (LoadedAssembly asm in relevantAssemblies.ToList())
{
var module = asm.GetMetadataFileOrNull();
if (CanResolveTypeInPEFile(module, typeRef, out var typeHandle))
{
ICompilation compilation = typeHandle.Kind == HandleKind.ExportedType
? new DecompilerTypeSystem(module, module.GetAssemblyResolver())
: new SimpleCompilation((PEFile)module, MinimalCorlib.Instance);
return memberRef == null
? typeRef.Resolve(new SimpleTypeResolveContext(compilation)) as ITypeDefinition
: memberRef.Resolve(new SimpleTypeResolveContext(compilation));
}
}
return null;
}
static bool CanResolveTypeInPEFile(MetadataFile module, ITypeReference typeRef, out EntityHandle typeHandle)
{
// We intentionally ignore reference assemblies, so that the loop continues looking for another assembly that might have a usable definition.
if (module.IsReferenceAssembly())
{
typeHandle = default;
return false;
}
switch (typeRef)
{
case GetPotentiallyNestedClassTypeReference topLevelType:
typeHandle = topLevelType.ResolveInPEFile(module);
return !typeHandle.IsNil;
case NestedTypeReference nestedType:
if (!CanResolveTypeInPEFile(module, nestedType.DeclaringTypeReference, out typeHandle))
return false;
if (typeHandle.Kind == HandleKind.ExportedType)
return true;
var typeDef = module.Metadata.GetTypeDefinition((TypeDefinitionHandle)typeHandle);
typeHandle = typeDef.GetNestedTypes().FirstOrDefault(t => {
var td = module.Metadata.GetTypeDefinition(t);
var typeName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(module.Metadata.GetString(td.Name), out int typeParameterCount);
return nestedType.AdditionalTypeParameterCount == typeParameterCount && nestedType.Name == typeName;
});
return !typeHandle.IsNil;
default:
typeHandle = default;
return false;
}
}
public void Initialize()
{
var loadPreviousAssemblies = Options.MiscSettingsPanel.CurrentMiscSettings.LoadPreviousAssemblies;
var sessionSettings = SettingsService.Instance.SessionSettings;
if (loadPreviousAssemblies)
{
this.assemblyList = SettingsService.Instance.AssemblyListManager.LoadList(sessionSettings.ActiveAssemblyList);
}
else
{
SettingsService.Instance.AssemblyListManager.ClearAll();
this.assemblyList = SettingsService.Instance.AssemblyListManager.CreateList(AssemblyListManager.DefaultListName);
}
HandleCommandLineArguments(App.CommandLineArguments);
if (assemblyList.GetAssemblies().Length == 0
&& assemblyList.ListName == AssemblyListManager.DefaultListName
&& loadPreviousAssemblies)
{
LoadInitialAssemblies();
}
ShowAssemblyList(this.assemblyList);
if (sessionSettings.ActiveAutoLoadedAssembly != null
&& File.Exists(sessionSettings.ActiveAutoLoadedAssembly))
{
this.assemblyList.Open(sessionSettings.ActiveAutoLoadedAssembly, true);
}
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => OpenAssemblies(SettingsService.Instance.SpySettings)));
}
void OpenAssemblies(ILSpySettings spySettings)
{
HandleCommandLineArgumentsAfterShowList(App.CommandLineArguments, spySettings);
AvalonEditTextOutput output = new();
if (FormatExceptions(App.StartupExceptions.ToArray(), output))
DockWorkspace.Instance.ShowText(output);
}
static bool FormatExceptions(App.ExceptionData[] exceptions, ITextOutput output)
{
var stringBuilder = new StringBuilder();
var result = exceptions.FormatExceptions(stringBuilder);
if (result)
{
output.Write(stringBuilder.ToString());
}
return result;
}
public void ShowAssemblyList(string name)
{
AssemblyList list = SettingsService.Instance.AssemblyListManager.LoadList(name);
//Only load a new list when it is a different one
if (list.ListName != CurrentAssemblyList.ListName)
{
ShowAssemblyList(list);
SelectNode(Root);
}
}
void ShowAssemblyList(AssemblyList assemblyList)
{
history.Clear();
if (this.assemblyList != null)
{
this.assemblyList.CollectionChanged -= assemblyList_CollectionChanged;
}
this.assemblyList = assemblyList;
assemblyList.CollectionChanged += assemblyList_CollectionChanged;
assemblyListTreeNode = new(assemblyList) {
Select = x => SelectNode(x)
};
Root = assemblyListTreeNode;
if (assemblyList.ListName == AssemblyListManager.DefaultListName)
#if DEBUG
this.Title = $"ILSpy {DecompilerVersionInfo.FullVersion}";
#else
this.Title = "ILSpy";
#endif
else
#if DEBUG
this.Title = $"ILSpy {DecompilerVersionInfo.FullVersion} - " + assemblyList.ListName;
#else
this.Title = "ILSpy - " + assemblyList.ListName;
#endif
}
void assemblyList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Reset)
{
history.RemoveAll(_ => true);
}
if (e.OldItems != null)
{
var oldAssemblies = new HashSet<LoadedAssembly>(e.OldItems.Cast<LoadedAssembly>());
history.RemoveAll(n => n.TreeNodes.Any(
nd => nd.AncestorsAndSelf().OfType<AssemblyTreeNode>().Any(
a => oldAssemblies.Contains(a.LoadedAssembly))));
}
MessageBus.Send(this, new CurrentAssemblyListChangedEventArgs(e));
}
void LoadInitialAssemblies()
{
// Called when loading an empty assembly list; so that
// the user can see something initially.
System.Reflection.Assembly[] initialAssemblies = {
typeof(object).Assembly,
typeof(Uri).Assembly,
typeof(System.Linq.Enumerable).Assembly,
typeof(System.Xml.XmlDocument).Assembly,
typeof(System.Windows.Markup.MarkupExtension).Assembly,
typeof(System.Windows.Rect).Assembly,
typeof(System.Windows.UIElement).Assembly,
typeof(System.Windows.FrameworkElement).Assembly
};
foreach (System.Reflection.Assembly asm in initialAssemblies)
assemblyList.OpenAssembly(asm.Location);
}
void LanguageSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Language" || e.PropertyName == "LanguageVersion")
{
DecompileSelectedNodes(recordHistory: false);
}
}
public AssemblyTreeNode FindAssemblyNode(LoadedAssembly asm)
{
return assemblyListTreeNode.FindAssemblyNode(asm);
}
#region Node Selection
public void SelectNode(SharpTreeNode node, bool inNewTabPage = false)
{
if (node == null)
return;
if (node.AncestorsAndSelf().Any(item => item.IsHidden))
{
MessageBox.Show(Properties.Resources.NavigationFailed, "ILSpy", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
if (inNewTabPage)
{
DockWorkspace.Instance.TabPages.Add();
SelectedItem = null;
}
if (SelectedItem == node)
{
Dispatcher.BeginInvoke(RefreshDecompiledView);
}
else
{
activeView?.ScrollIntoView(node);
SelectedItem = node;
}
}
internal void SelectNodes(IEnumerable<SharpTreeNode> nodes, bool inNewTabPage = false, bool setFocus = true, bool changingTab = false, bool ignoreCompilationRequests = false)
{
this.ignoreDecompilationRequests = ignoreCompilationRequests;
try
{
if (inNewTabPage)
{
DockWorkspace.Instance.TabPages.Add();
}
// Ensure nodes exist
var nodesList = nodes.Select(n => FindNodeByPath(GetPathForNode(n), true))
.Where(n => n != null)
.ToArray();
if (!nodesList.Any() || nodesList.Any(n => n.AncestorsAndSelf().Any(a => a.IsHidden)))
{
return;
}
this.changingActiveTab = changingTab || inNewTabPage;
var currentFocused = Keyboard.FocusedElement;
try
{
if (SelectedItems.SequenceEqual(nodesList))
{
Dispatcher.BeginInvoke(RefreshDecompiledView);
return;
}
this.SelectedItems.Clear();
this.SelectedItems.AddRange(nodesList);
}
finally
{
if (!setFocus)
currentFocused.Focus();
this.changingActiveTab = false;
}
}
finally
{
this.ignoreDecompilationRequests = false;
}
}
/// <summary>
/// Retrieves a node using the .ToString() representations of its ancestors.
/// </summary>
public SharpTreeNode FindNodeByPath(string[] path, bool returnBestMatch)
{
if (path == null)
return null;
SharpTreeNode node = Root;
SharpTreeNode bestMatch = node;
foreach (var element in path)
{
if (node == null)
break;
bestMatch = node;
node.EnsureLazyChildren();
if (node is ILSpyTreeNode ilSpyTreeNode)
ilSpyTreeNode.EnsureChildrenFiltered();
node = node.Children.FirstOrDefault(c => c.ToString() == element);
}
if (returnBestMatch)
return node ?? bestMatch;
else
return node;
}
/// <summary>
/// Gets the .ToString() representation of the node's ancestors.
/// </summary>
public static string[] GetPathForNode(SharpTreeNode node)
{
if (node == null)
return null;
List<string> path = new List<string>();
while (node.Parent != null)
{
path.Add(node.ToString());
node = node.Parent;
}
path.Reverse();
return path.ToArray();
}
public ILSpyTreeNode FindTreeNode(object reference)
{
switch (reference)
{
case LoadedAssembly lasm:
return assemblyListTreeNode.FindAssemblyNode(lasm);
case MetadataFile asm:
return assemblyListTreeNode.FindAssemblyNode(asm);
case Resource res:
return assemblyListTreeNode.FindResourceNode(res);
case ValueTuple<Resource, string> resName:
return assemblyListTreeNode.FindResourceNode(resName.Item1, resName.Item2);
case ITypeDefinition type:
return assemblyListTreeNode.FindTypeNode(type);
case IField fd:
return assemblyListTreeNode.FindFieldNode(fd);
case IMethod md:
return assemblyListTreeNode.FindMethodNode(md);
case IProperty pd:
return assemblyListTreeNode.FindPropertyNode(pd);
case IEvent ed:
return assemblyListTreeNode.FindEventNode(ed);
case INamespace nd:
return assemblyListTreeNode.FindNamespaceNode(nd);
default:
return null;
}
}
private void JumpToReference(object sender, NavigateToReferenceEventArgs e)
{
JumpToReferenceAsync(e.Reference, e.InNewTabPage).HandleExceptions();
}
/// <summary>
/// Jumps to the specified reference.
/// </summary>
/// <returns>
/// Returns a task that will signal completion when the decompilation of the jump target has finished.
/// The task will be marked as canceled if the decompilation is canceled.
/// </returns>
private Task JumpToReferenceAsync(object reference, bool inNewTabPage = false)
{
var decompilationTask = Task.CompletedTask;
switch (reference)
{
case Decompiler.Disassembler.OpCodeInfo opCode:
MainWindow.OpenLink(opCode.Link);
break;
case EntityReference unresolvedEntity:
string protocol = unresolvedEntity.Protocol;
var file = unresolvedEntity.ResolveAssembly(assemblyList);
if (file == null)
{
break;
}
if (protocol != "decompile")
{
var protocolHandlers = App.ExportProvider.GetExportedValues<IProtocolHandler>();
foreach (var handler in protocolHandlers)
{
var node = handler.Resolve(protocol, file, unresolvedEntity.Handle, out bool newTabPage);
if (node != null)
{
SelectNode(node, newTabPage || inNewTabPage);
return decompilationTask;
}
}
}
var possibleToken = MetadataTokenHelpers.TryAsEntityHandle(MetadataTokens.GetToken(unresolvedEntity.Handle));
if (possibleToken != null)
{
var typeSystem = new DecompilerTypeSystem(file, file.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached);
reference = typeSystem.MainModule.ResolveEntity(possibleToken.Value);
goto default;
}
break;
default:
ILSpyTreeNode treeNode = FindTreeNode(reference);
if (treeNode != null)
SelectNode(treeNode, inNewTabPage);
break;
}
return decompilationTask;
}
#endregion
public void LoadAssemblies(IEnumerable<string> fileNames, List<LoadedAssembly> loadedAssemblies = null, bool focusNode = true)
{
var currentFocus = Keyboard.FocusedElement;
AssemblyTreeNode lastNode = null;
foreach (string file in fileNames)
{
var assembly = assemblyList.OpenAssembly(file);
if (loadedAssemblies != null)
{
loadedAssemblies.Add(assembly);
}
else
{
var node = assemblyListTreeNode.FindAssemblyNode(assembly);
if (node != null && focusNode)
{
lastNode = node;
SelectedItems.Add(node);
}
}
}
if (!focusNode)
{
currentFocus?.Focus();
}
else if (lastNode != null)
{
activeView?.FocusNode(lastNode);
}
}
#region Decompile (TreeView_SelectionChanged)
void TreeView_SelectionChanged()
{
DecompilerTextViewState state = null;
// These are probably no longer needed and can be removed!
Debug.Assert(!refreshInProgress);
Debug.Assert(!changingActiveTab);
if (refreshInProgress || changingActiveTab)
{
state = DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState;
}
var delayDecompilationRequestDueToContextMenu = Mouse.RightButton == MouseButtonState.Pressed;
if (!changingActiveTab && !delayDecompilationRequestDueToContextMenu)
{
DecompileSelectedNodes(state);
}
else
{
ContextMenuProvider.ContextMenuClosed += ContextMenuClosed;
}
MessageBus.Send(this, new AssemblyTreeSelectionChangedEventArgs());
return;
void ContextMenuClosed(object sender, EventArgs e)
{
ContextMenuProvider.ContextMenuClosed -= ContextMenuClosed;
Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {
if (Mouse.RightButton != MouseButtonState.Pressed)
{
DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState);
}
});
}
}
private bool ignoreDecompilationRequests;
public void DecompileSelectedNodes(DecompilerTextViewState newState = null, bool recordHistory = true)
{
if (ignoreDecompilationRequests)
return;
if (SelectedItems.Count == 0 && refreshInProgress)
return;
if (recordHistory)
{
var tabPage = DockWorkspace.Instance.ActiveTabPage;
var currentState = tabPage.GetState();
if (currentState != null)
history.UpdateCurrent(new NavigationState(tabPage, currentState));
history.Record(new NavigationState(tabPage, SelectedItems));
}
DockWorkspace.Instance.ActiveTabPage.SupportsLanguageSwitching = true;
if (SelectedItems.Count == 1)
{
if (SelectedItem is ILSpyTreeNode node && node.View(DockWorkspace.Instance.ActiveTabPage))
return;
}
if (newState?.ViewedUri != null)
{
MainWindow.Instance.NavigateTo(new(newState.ViewedUri, null), recordHistory: false);
return;
}
var options = MainWindow.Instance.CreateDecompilationOptions();
options.TextViewState = newState;
DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, options));
}
public void RefreshDecompiledView()
{
try
{
refreshInProgress = true;
DecompileSelectedNodes();
}
finally
{
refreshInProgress = false;
}
}
public Language CurrentLanguage => SettingsService.Instance.SessionSettings.LanguageSettings.Language;
public LanguageVersion CurrentLanguageVersion => SettingsService.Instance.SessionSettings.LanguageSettings.LanguageVersion;
public IEnumerable<ILSpyTreeNode> SelectedNodes {
get {
return GetTopLevelSelection().OfType<ILSpyTreeNode>();
}
}
#endregion
public void Refresh()
{
var currentFocus = Keyboard.FocusedElement;
try
{
refreshInProgress = true;
var path = GetPathForNode(SelectedItem);
ShowAssemblyList(SettingsService.Instance.AssemblyListManager.LoadList(assemblyList.ListName));
SelectNode(FindNodeByPath(path, true), inNewTabPage: false);
}
finally
{
refreshInProgress = false;
currentFocus?.Focus();
}
}
public void UnselectAll(bool ignoreCompilationRequests = false)
{
this.ignoreDecompilationRequests = ignoreCompilationRequests;
SelectedItems.Clear();
this.ignoreDecompilationRequests = false;
}
public IEnumerable<SharpTreeNode> GetTopLevelSelection()
{
var selection = this.SelectedItems;
var selectionHash = new HashSet<SharpTreeNode>(selection);
return selection.Where(item => item.Ancestors().All(a => !selectionHash.Contains(a)));
}
public void SetActiveView(AssemblyListPane activeView)
{
this.activeView = activeView;
}
public void SortAssemblyList()
{
using (activeView?.LockUpdates())
{
CurrentAssemblyList.Sort(AssemblyComparer.Instance);
}
}
private class AssemblyComparer : IComparer<LoadedAssembly>
{
public static readonly AssemblyComparer Instance = new();
int IComparer<LoadedAssembly>.Compare(LoadedAssembly x, LoadedAssembly y)
{
return string.Compare(x?.ShortName, y?.ShortName, StringComparison.CurrentCulture);
}
}
public void CollapseAll()
{
using (activeView.LockUpdates())
{
CollapseChildren(Root);
}
}
static void CollapseChildren(SharpTreeNode node)
{
foreach (var child in node.Children)
{
if (!child.IsExpanded)
continue;
CollapseChildren(child);
child.IsExpanded = false;
}
}
}
}

5
ILSpy/Commands/DecompileAllCommand.cs

@ -28,7 +28,6 @@ using System.Threading.Tasks; @@ -28,7 +28,6 @@ using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
using TomsToolbox.Essentials;
@ -49,7 +48,7 @@ namespace ICSharpCode.ILSpy @@ -49,7 +48,7 @@ namespace ICSharpCode.ILSpy
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
Parallel.ForEach(
Partitioner.Create(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), loadBalance: true),
Partitioner.Create(MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.GetAssemblies(), loadBalance: true),
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },
delegate (LoadedAssembly asm) {
if (!asm.HasLoadError)
@ -96,7 +95,7 @@ namespace ICSharpCode.ILSpy @@ -96,7 +95,7 @@ namespace ICSharpCode.ILSpy
{
const int numRuns = 100;
var language = SettingsService.Instance.SessionSettings.LanguageSettings.Language;
var nodes = MainWindow.Instance.SelectedNodes.ToArray();
var nodes = MainWindow.Instance.AssemblyTreeModel.SelectedNodes.ToArray();
var options = MainWindow.Instance.CreateDecompilationOptions();
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
options.CancellationToken = ct;

2
ILSpy/Commands/DecompileCommand.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.ILSpy.Commands @@ -66,7 +66,7 @@ namespace ICSharpCode.ILSpy.Commands
selection = entity;
}
if (selection != null)
MainWindow.Instance.JumpToReference(selection);
MessageBus.Send(this, new NavigateToReferenceEventArgs(selection));
}
}
}

17
ILSpy/Commands/DecompileInNewViewCommand.cs

@ -23,11 +23,11 @@ using System.Linq; @@ -23,11 +23,11 @@ using System.Linq;
using System.Windows.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using TomsToolbox.Essentials;
namespace ICSharpCode.ILSpy.Commands
{
[ExportContextMenuEntry(Header = nameof(Resources.DecompileToNewPanel), InputGestureText = "MMB", Icon = "images/Search", Category = nameof(Resources.Analyze), Order = 90)]
@ -53,18 +53,18 @@ namespace ICSharpCode.ILSpy.Commands @@ -53,18 +53,18 @@ namespace ICSharpCode.ILSpy.Commands
{
if (context.SelectedTreeNodes != null)
{
if (context.TreeView != MainWindow.Instance.AssemblyTreeView)
if (context.TreeView.DataContext != MainWindow.Instance.AssemblyTreeModel)
{
return context.SelectedTreeNodes.OfType<IMemberTreeNode>().Select(FindTreeNode).Where(n => n != null);
return context.SelectedTreeNodes.OfType<IMemberTreeNode>().Select(FindTreeNode).ExceptNullItems();
}
else
{
return context.SelectedTreeNodes.OfType<ILSpyTreeNode>().Where(n => n != null);
return context.SelectedTreeNodes.OfType<ILSpyTreeNode>();
}
}
else if (context.Reference?.Reference is IEntity entity)
{
if (MainWindow.Instance.FindTreeNode(entity) is ILSpyTreeNode node)
if (MainWindow.Instance.AssemblyTreeModel.FindTreeNode(entity) is { } node)
{
return new[] { node };
}
@ -75,7 +75,7 @@ namespace ICSharpCode.ILSpy.Commands @@ -75,7 +75,7 @@ namespace ICSharpCode.ILSpy.Commands
{
if (node is ILSpyTreeNode ilspyNode)
return ilspyNode;
return MainWindow.Instance.FindTreeNode(node.Member);
return MainWindow.Instance.AssemblyTreeModel.FindTreeNode(node.Member);
}
}
@ -84,8 +84,7 @@ namespace ICSharpCode.ILSpy.Commands @@ -84,8 +84,7 @@ namespace ICSharpCode.ILSpy.Commands
if (nodes.Length == 0)
return;
MainWindow.Instance.SelectNodes(nodes, inNewTabPage: true);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView);
MainWindow.Instance.AssemblyTreeModel.SelectNodes(nodes, inNewTabPage: true);
}
}
}

2
ILSpy/Commands/DisassembleAllCommand.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
Parallel.ForEach(
Partitioner.Create(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), loadBalance: true),
Partitioner.Create(MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.GetAssemblies(), loadBalance: true),
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },
delegate (LoadedAssembly asm) {
if (!asm.HasLoadError)

6
ILSpy/Commands/GeneratePdbContextMenuEntry.cs

@ -110,14 +110,14 @@ namespace ICSharpCode.ILSpy @@ -110,14 +110,14 @@ namespace ICSharpCode.ILSpy
{
public override bool CanExecute(object parameter)
{
return MainWindow.Instance.SelectedNodes?.Count() == 1
&& MainWindow.Instance.SelectedNodes?.FirstOrDefault() is AssemblyTreeNode tn
return MainWindow.Instance.AssemblyTreeModel.SelectedNodes?.Count() == 1
&& MainWindow.Instance.AssemblyTreeModel.SelectedNodes?.FirstOrDefault() is AssemblyTreeNode tn
&& !tn.LoadedAssembly.HasLoadError;
}
public override void Execute(object parameter)
{
var assembly = (MainWindow.Instance.SelectedNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
var assembly = (MainWindow.Instance.AssemblyTreeModel.SelectedNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
if (assembly == null)
return;
GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly);

4
ILSpy/Commands/Pdb2XmlCommand.cs

@ -40,14 +40,14 @@ namespace ICSharpCode.ILSpy @@ -40,14 +40,14 @@ namespace ICSharpCode.ILSpy
{
public override bool CanExecute(object parameter)
{
var selectedNodes = MainWindow.Instance.SelectedNodes;
var selectedNodes = MainWindow.Instance.AssemblyTreeModel.SelectedNodes;
return selectedNodes?.Any() == true
&& selectedNodes.All(n => n is AssemblyTreeNode asm && !asm.LoadedAssembly.HasLoadError);
}
public override void Execute(object parameter)
{
Execute(MainWindow.Instance.SelectedNodes.OfType<AssemblyTreeNode>());
Execute(MainWindow.Instance.AssemblyTreeModel.SelectedNodes.OfType<AssemblyTreeNode>());
}
internal static void Execute(IEnumerable<AssemblyTreeNode> nodes)

10
ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs

@ -29,16 +29,16 @@ namespace ICSharpCode.ILSpy @@ -29,16 +29,16 @@ namespace ICSharpCode.ILSpy
{
public override bool CanExecute(object parameter)
{
return MainWindow.Instance.CurrentAssemblyList?.GetAssemblies().Any(l => l.HasLoadError) == true;
return MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList?.GetAssemblies().Any(l => l.HasLoadError) == true;
}
public override void Execute(object parameter)
{
foreach (var asm in MainWindow.Instance.CurrentAssemblyList.GetAssemblies())
foreach (var asm in MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.GetAssemblies())
{
if (!asm.HasLoadError)
continue;
var node = MainWindow.Instance.AssemblyListTreeNode.FindAssemblyNode(asm);
var node = MainWindow.Instance.AssemblyTreeModel.FindAssemblyNode(asm);
if (node != null && node.CanDelete())
node.Delete();
}
@ -51,12 +51,12 @@ namespace ICSharpCode.ILSpy @@ -51,12 +51,12 @@ namespace ICSharpCode.ILSpy
{
public override bool CanExecute(object parameter)
{
return MainWindow.Instance.CurrentAssemblyList?.Count > 0;
return MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList?.Count > 0;
}
public override void Execute(object parameter)
{
MainWindow.Instance.CurrentAssemblyList?.Clear();
MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList?.Clear();
}
}
}

1
ILSpy/Commands/SaveCodeContextMenuEntry.cs

@ -32,7 +32,6 @@ using Microsoft.Win32; @@ -32,7 +32,6 @@ using Microsoft.Win32;
using ICSharpCode.ILSpyX.TreeView;
using System.ComponentModel.Composition;
using ICSharpCode.ILSpy.Util;
namespace ICSharpCode.ILSpy.TextView
{

6
ILSpy/Commands/SelectPdbContextMenuEntry.cs

@ -48,10 +48,10 @@ namespace ICSharpCode.ILSpy @@ -48,10 +48,10 @@ namespace ICSharpCode.ILSpy
await assembly.LoadDebugInfo(dlg.FileName);
}
var node = (AssemblyTreeNode)MainWindow.Instance.FindNodeByPath(new[] { assembly.FileName }, true);
var node = (AssemblyTreeNode)MainWindow.Instance.AssemblyTreeModel.FindNodeByPath(new[] { assembly.FileName }, true);
node.UpdateToolTip();
MainWindow.Instance.SelectNode(node);
MainWindow.Instance.RefreshDecompiledView();
MainWindow.Instance.AssemblyTreeModel.SelectNode(node);
MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView();
}
public bool IsEnabled(TextViewContext context) => true;

3
ILSpy/Commands/SetThemeCommand.cs

@ -1,5 +1,4 @@ @@ -1,5 +1,4 @@
using ICSharpCode.ILSpy.Util;

namespace ICSharpCode.ILSpy.Commands
{
public class SetThemeCommand : SimpleCommand

1
ILSpy/Commands/ShowCFGContextMenuEntry.cs

@ -6,7 +6,6 @@ using System.Windows; @@ -6,7 +6,6 @@ using System.Windows;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.ControlFlow;
using ICSharpCode.ILSpy.Util;
namespace ICSharpCode.ILSpy.Commands
{

23
ILSpy/Commands/SortAssemblyListCommand.cs

@ -29,17 +29,11 @@ namespace ICSharpCode.ILSpy @@ -29,17 +29,11 @@ namespace ICSharpCode.ILSpy
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources.SortAssembly_listName), MenuIcon = "Images/Sort", MenuCategory = nameof(Resources.View))]
[ExportToolbarCommand(ToolTip = nameof(Resources.SortAssemblyListName), ToolbarIcon = "Images/Sort", ToolbarCategory = nameof(Resources.View))]
[PartCreationPolicy(CreationPolicy.Shared)]
sealed class SortAssemblyListCommand : SimpleCommand, IComparer<LoadedAssembly>
sealed class SortAssemblyListCommand : SimpleCommand
{
public override void Execute(object parameter)
{
using (MainWindow.Instance.AssemblyTreeView.LockUpdates())
MainWindow.Instance.CurrentAssemblyList.Sort(this);
}
int IComparer<LoadedAssembly>.Compare(LoadedAssembly x, LoadedAssembly y)
{
return string.Compare(x.ShortName, y.ShortName, StringComparison.CurrentCulture);
MainWindow.Instance.AssemblyTreeModel.SortAssemblyList();
}
}
@ -50,19 +44,8 @@ namespace ICSharpCode.ILSpy @@ -50,19 +44,8 @@ namespace ICSharpCode.ILSpy
{
public override void Execute(object parameter)
{
using (MainWindow.Instance.AssemblyTreeView.LockUpdates())
CollapseChildren(MainWindow.Instance.AssemblyTreeView.Root);
MainWindow.Instance.AssemblyTreeModel.CollapseAll();
void CollapseChildren(SharpTreeNode node)
{
foreach (var child in node.Children)
{
if (!child.IsExpanded)
continue;
CollapseChildren(child);
child.IsExpanded = false;
}
}
}
}
}

33
ILSpy/ContextMenuEntry.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@ -32,6 +33,7 @@ using ICSharpCode.ILSpy.Controls.TreeView; @@ -32,6 +33,7 @@ using ICSharpCode.ILSpy.Controls.TreeView;
using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Composition;
using TomsToolbox.Essentials;
namespace ICSharpCode.ILSpy
{
@ -168,6 +170,13 @@ namespace ICSharpCode.ILSpy @@ -168,6 +170,13 @@ namespace ICSharpCode.ILSpy
internal class ContextMenuProvider
{
private static readonly WeakEventSource<EventArgs> ContextMenuClosedEventSource = new();
public static event EventHandler<EventArgs> ContextMenuClosed {
add => ContextMenuClosedEventSource.Subscribe(value);
remove => ContextMenuClosedEventSource.Unsubscribe(value);
}
/// <summary>
/// Enables extensible context menu support for the specified tree view.
/// </summary>
@ -203,37 +212,40 @@ namespace ICSharpCode.ILSpy @@ -203,37 +212,40 @@ namespace ICSharpCode.ILSpy
dataGrid.ContextMenu = new ContextMenu();
}
readonly Control control;
readonly SharpTreeView treeView;
readonly DecompilerTextView textView;
readonly ListBox listBox;
readonly DataGrid dataGrid;
readonly IExport<IContextMenuEntry, IContextMenuEntryMetadata>[] entries;
private ContextMenuProvider()
private ContextMenuProvider(Control control)
{
entries = App.ExportProvider.GetExports<IContextMenuEntry, IContextMenuEntryMetadata>().ToArray();
this.control = control;
}
ContextMenuProvider(DecompilerTextView textView)
: this()
: this((Control)textView)
{
this.textView = textView ?? throw new ArgumentNullException(nameof(textView));
}
ContextMenuProvider(SharpTreeView treeView)
: this()
: this((Control)treeView)
{
this.treeView = treeView ?? throw new ArgumentNullException(nameof(treeView));
}
ContextMenuProvider(ListBox listBox)
: this()
: this((Control)listBox)
{
this.listBox = listBox ?? throw new ArgumentNullException(nameof(listBox));
}
ContextMenuProvider(DataGrid dataGrid)
: this()
: this((Control)dataGrid)
{
this.dataGrid = dataGrid ?? throw new ArgumentNullException(nameof(dataGrid));
}
@ -289,7 +301,18 @@ namespace ICSharpCode.ILSpy @@ -289,7 +301,18 @@ namespace ICSharpCode.ILSpy
bool ShowContextMenu(TextViewContext context, out ContextMenu menu)
{
// Closing event is raised on the control where mouse is clicked, not on the control that opened the menu, so we hook on the global window event.
var window = Window.GetWindow(control)!;
window.ContextMenuClosing += ContextMenu_Closing;
void ContextMenu_Closing(object sender, EventArgs e)
{
window.ContextMenuClosing -= ContextMenu_Closing;
ContextMenuClosedEventSource.Raise(this, EventArgs.Empty);
}
menu = new ContextMenu();
var menuGroups = new Dictionary<string, IExport<IContextMenuEntry, IContextMenuEntryMetadata>[]>();
IExport<IContextMenuEntry, IContextMenuEntryMetadata>[] topLevelGroup = null;
foreach (var group in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.ParentMenuID))

1
ILSpy/Controls/TreeView/SharpTreeView.cs

@ -158,6 +158,7 @@ namespace ICSharpCode.ILSpy.Controls.TreeView @@ -158,6 +158,7 @@ namespace ICSharpCode.ILSpy.Controls.TreeView
if (flattener != null)
{
flattener.Stop();
flattener.CollectionChanged -= flattener_CollectionChanged;
}
if (Root != null)
{

6
ILSpy/Docking/DockWorkspace.cs

@ -33,7 +33,6 @@ using ICSharpCode.AvalonEdit.Highlighting; @@ -33,7 +33,6 @@ using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using TomsToolbox.Wpf;
@ -136,8 +135,7 @@ namespace ICSharpCode.ILSpy.Docking @@ -136,8 +135,7 @@ namespace ICSharpCode.ILSpy.Docking
{
if (state.DecompiledNodes != null)
{
MainWindow.Instance.SelectNodes(state.DecompiledNodes,
inNewTabPage: false, setFocus: true, changingActiveTab: true);
MainWindow.Instance.AssemblyTreeModel.SelectNodes(state.DecompiledNodes, inNewTabPage: false, setFocus: true, changingTab: true);
}
else
{
@ -216,7 +214,7 @@ namespace ICSharpCode.ILSpy.Docking @@ -216,7 +214,7 @@ namespace ICSharpCode.ILSpy.Docking
CloseAllTabs();
SessionSettings.DockLayout.Reset();
InitializeLayout(MainWindow.Instance.dockManager);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView);
}
static readonly PropertyInfo previousContainerProperty = typeof(LayoutContent).GetProperty("PreviousContainer", BindingFlags.NonPublic | BindingFlags.Instance);

1
ILSpy/ExtensionMethods.cs

@ -27,7 +27,6 @@ using System.Windows.Media; @@ -27,7 +27,6 @@ using System.Windows.Media;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy

1
ILSpy/GlobalUsings.cs

@ -0,0 +1 @@ @@ -0,0 +1 @@
global using ICSharpCode.ILSpy.Util;

1
ILSpy/LanguageSettings.cs

@ -23,7 +23,6 @@ using System.Linq; @@ -23,7 +23,6 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy

1
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -34,7 +34,6 @@ using ICSharpCode.Decompiler.Disassembler; @@ -34,7 +34,6 @@ using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Extensions;

7
ILSpy/Languages/CSharpLanguage.cs

@ -41,7 +41,6 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -41,7 +41,6 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
using LanguageVersion = ICSharpCode.ILSpyX.LanguageVersion;
@ -359,15 +358,15 @@ namespace ICSharpCode.ILSpy @@ -359,15 +358,15 @@ namespace ICSharpCode.ILSpy
void AddReferenceWarningMessage(MetadataFile module, ITextOutput output)
{
var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetMetadataFileOrNull() == module);
var loadedAssembly = MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetMetadataFileOrNull() == module);
if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors)
return;
string line1 = Properties.Resources.WarningSomeAssemblyReference;
string line2 = Properties.Resources.PropertyManuallyMissingReferencesListLoadedAssemblies;
AddWarningMessage(module, output, line1, line2, Properties.Resources.ShowAssemblyLoad, Images.ViewCode, delegate {
ILSpyTreeNode assemblyNode = MainWindow.Instance.FindTreeNode(module);
ILSpyTreeNode assemblyNode = MainWindow.Instance.AssemblyTreeModel.FindTreeNode(module);
assemblyNode.EnsureLazyChildren();
MainWindow.Instance.SelectNode(assemblyNode.Children.OfType<ReferenceFolderTreeNode>().Single());
MainWindow.Instance.AssemblyTreeModel.SelectNode(assemblyNode.Children.OfType<ReferenceFolderTreeNode>().Single());
});
}

1
ILSpy/Languages/ILLanguage.cs

@ -30,7 +30,6 @@ using ICSharpCode.Decompiler.Solution; @@ -30,7 +30,6 @@ using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy

46
ILSpy/MainWindow.xaml

@ -21,52 +21,8 @@ @@ -21,52 +21,8 @@
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes"
xmlns:toms="urn:TomsToolbox"
xmlns:viewModels="clr-namespace:ICSharpCode.ILSpy.ViewModels"
xmlns:treeNodes="clr-namespace:ICSharpCode.ILSpy.TreeNodes"
xmlns:util="clr-namespace:ICSharpCode.ILSpy.Util"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
<Window.Resources>
<tv:SharpTreeView x:Key="AssemblyTreeView"
AutomationProperties.Name="Assemblies and Classes"
SelectionChanged="TreeView_SelectionChanged"
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0" Visibility="Visible">
<tv:SharpTreeView.ItemContainerStyle>
<Style TargetType="tv:SharpTreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type tv:SharpTreeViewItem}" d:DataContext="{d:DesignInstance treeNodes:ILSpyTreeNode}">
<Border Background="Transparent">
<Border Background="{TemplateBinding Background}">
<tv:SharpTreeNodeView x:Name="nodeView" HorizontalAlignment="Left" />
</Border>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsAutoLoaded}" Value="True">
<Setter Property="Foreground" Value="SteelBlue" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPublicAPI}" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</DataTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="nodeView" Property="TextBackground" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter TargetName="nodeView" Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="nodeView" Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</tv:SharpTreeView.ItemContainerStyle>
</tv:SharpTreeView>
<DataTemplate DataType="{x:Type viewModels:AssemblyListPaneModel}">
<ContentControl Content="{StaticResource AssemblyTreeView}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:TabPageModel}">
<ContentPresenter Content="{Binding Content}" />
@ -223,7 +179,7 @@ @@ -223,7 +179,7 @@
<!-- Update panel -->
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1" Name="updatePanel" Visibility="Collapsed">
<DockPanel KeyboardNavigation.TabNavigation="Contained">
<Button DockPanel.Dock="Right" Click="updatePanelCloseButtonClick" MinWidth="0">X</Button>
<Button DockPanel.Dock="Right" Click="UpdatePanelCloseButtonClick" MinWidth="0">X</Button>
<StackPanel Orientation="Horizontal">
<TextBlock Name="updatePanelMessage" Margin="4,0" VerticalAlignment="Center"
Text="{x:Static properties:Resources.ILSpyVersionAvailable}" />

820
ILSpy/MainWindow.xaml.cs

File diff suppressed because it is too large Load Diff

2
ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference("metadata", classLayout.Parent));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference("metadata", classLayout.Parent)));
}
string parentTooltip;

2
ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs

@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, constant.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, constant.Parent, protocol: "metadata")));
}
string parentTooltip;

4
ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, customAttr.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, customAttr.Parent, protocol: "metadata")));
}
string parentTooltip;
@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnConstructorClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, customAttr.Constructor, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, customAttr.Constructor, protocol: "metadata")));
}
string constructorTooltip;

2
ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs

@ -84,7 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -84,7 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, declSecAttr.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, declSecAttr.Parent, protocol: "metadata")));
}
string parentTooltip;

4
ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, eventMap.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, eventMap.Parent, protocol: "metadata")));
}
string parentTooltip;
@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnEventListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, eventMap.EventList, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, eventMap.EventList, protocol: "metadata")));
}
string eventListTooltip;

2
ILSpy/Metadata/CorTables/EventTableTreeNode.cs

@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnTypeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, eventDef.Type, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, eventDef.Type, protocol: "metadata")));
}
string typeTooltip;

2
ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs

@ -107,7 +107,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -107,7 +107,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnImplementationClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, type.Implementation, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, type.Implementation, protocol: "metadata")));
}
string implementationTooltip;

2
ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs

@ -96,7 +96,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -96,7 +96,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnFieldClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, fieldLayout.Field, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, fieldLayout.Field, protocol: "metadata")));
}
string fieldTooltip;

2
ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, fieldMarshal.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, fieldMarshal.Parent, protocol: "metadata")));
}
string parentTooltip;

2
ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs

@ -99,7 +99,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -99,7 +99,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnFieldClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, fieldRVA.Field, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, fieldRVA.Field, protocol: "metadata")));
}
string fieldTooltip;

4
ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs

@ -84,7 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -84,7 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnOwnerClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, genericParamConstraint.Parameter, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, genericParamConstraint.Parameter, protocol: "metadata")));
}
string ownerTooltip;
@ -108,7 +108,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -108,7 +108,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnTypeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, genericParamConstraint.Type, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, genericParamConstraint.Type, protocol: "metadata")));
}
string typeTooltip;

2
ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs

@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnOwnerClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, genericParam.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, genericParam.Parent, protocol: "metadata")));
}
string ownerTooltip;

4
ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs

@ -113,7 +113,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -113,7 +113,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMemberForwardedClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, implMap.MemberForwarded, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, implMap.MemberForwarded, protocol: "metadata")));
}
string memberForwardedTooltip;
@ -124,7 +124,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -124,7 +124,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnImportScopeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, implMap.ImportScope, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, implMap.ImportScope, protocol: "metadata")));
}
string importScopeTooltip;

4
ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs

@ -96,7 +96,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -96,7 +96,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnClassClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, interfaceImpl.Class, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, interfaceImpl.Class, protocol: "metadata")));
}
string classTooltip;
@ -107,7 +107,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -107,7 +107,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnInterfaceClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, interfaceImpl.Interface, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, interfaceImpl.Interface, protocol: "metadata")));
}
string interfaceTooltip;

2
ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs

@ -93,7 +93,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -93,7 +93,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnImplementationClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, manifestResource.Implementation, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, manifestResource.Implementation, protocol: "metadata")));
}
string implementationTooltip;

2
ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, memberRef.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, memberRef.Parent, protocol: "metadata")));
}
string parentTooltip;

6
ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs

@ -82,7 +82,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -82,7 +82,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodDeclarationClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodImpl.MethodDeclaration, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodImpl.MethodDeclaration, protocol: "metadata")));
}
string methodDeclarationTooltip;
@ -93,7 +93,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -93,7 +93,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodBodyClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodImpl.MethodBody, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodImpl.MethodBody, protocol: "metadata")));
}
string methodBodyTooltip;
@ -104,7 +104,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -104,7 +104,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnTypeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodImpl.Type, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodImpl.Type, protocol: "metadata")));
}
string typeTooltip;

4
ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs

@ -90,7 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -90,7 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, method, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, method, protocol: "metadata")));
}
string methodTooltip;
@ -101,7 +101,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -101,7 +101,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnAssociationClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, association, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, association, protocol: "metadata")));
}
string associationTooltip;

2
ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs

@ -85,7 +85,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -85,7 +85,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodSpec.Method, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodSpec.Method, protocol: "metadata")));
}
string methodTooltip;

2
ILSpy/Metadata/CorTables/MethodTableTreeNode.cs

@ -118,7 +118,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -118,7 +118,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParamListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodDef.GetParameters().FirstOrDefault(), protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodDef.GetParameters().FirstOrDefault(), protocol: "metadata")));
}
string paramListTooltip;

4
ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnNestedClassClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, nestedClass.Nested, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Nested, protocol: "metadata")));
}
string nestedClassTooltip;
@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnEnclosingClassClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, nestedClass.Enclosing, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Enclosing, protocol: "metadata")));
}
string enclosingClassTooltip;

4
ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, propertyMap.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, propertyMap.Parent, protocol: "metadata")));
}
string parentTooltip;
@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnPropertyListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, propertyMap.PropertyList, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, propertyMap.PropertyList, protocol: "metadata")));
}
string propertyListTooltip;

6
ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnBaseTypeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeDef.BaseType, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeDef.BaseType, protocol: "metadata")));
}
public string BaseTypeTooltip {
@ -142,7 +142,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -142,7 +142,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnFieldListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeDef.GetFields().FirstOrDefault(), protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeDef.GetFields().FirstOrDefault(), protocol: "metadata")));
}
string fieldListTooltip;
@ -160,7 +160,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -160,7 +160,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeDef.GetMethods().FirstOrDefault(), protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeDef.GetMethods().FirstOrDefault(), protocol: "metadata")));
}
string methodListTooltip;

2
ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnResolutionScopeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeRef.ResolutionScope, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeRef.ResolutionScope, protocol: "metadata")));
}
string resolutionScopeTooltip;

1
ILSpy/Metadata/DebugMetadataTablesTreeNode.cs

@ -21,7 +21,6 @@ using System.Reflection.Metadata.Ecma335; @@ -21,7 +21,6 @@ using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata

2
ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs

@ -188,7 +188,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -188,7 +188,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, debugInfo.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, debugInfo.Parent, protocol: "metadata")));
}
string parentTooltip;

2
ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs

@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.Parent, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.Parent, protocol: "metadata")));
}
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]

8
ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs

@ -81,7 +81,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -81,7 +81,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.Method, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.Method, protocol: "metadata")));
}
string methodTooltip;
@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnImportScopeClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.ImportScope, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.ImportScope, protocol: "metadata")));
}
[ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -100,7 +100,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -100,7 +100,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnVariableListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.GetLocalVariables().FirstOrDefault(), protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.GetLocalVariables().FirstOrDefault(), protocol: "metadata")));
}
[ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -108,7 +108,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -108,7 +108,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnConstantListClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.GetLocalConstants().FirstOrDefault(), protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.GetLocalConstants().FirstOrDefault(), protocol: "metadata")));
}
public int StartOffset => localScope.StartOffset;

4
ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnDocumentClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, debugInfo.Document, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, debugInfo.Document, protocol: "metadata")));
}
public string DocumentTooltip {
@ -116,7 +116,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -116,7 +116,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnLocalSignatureClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, debugInfo.LocalSignature, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, debugInfo.LocalSignature, protocol: "metadata")));
}
public string LocalSignatureTooltip {

4
ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMoveNextMethodClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, moveNextMethod, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, moveNextMethod, protocol: "metadata")));
}
string moveNextMethodTooltip;
@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnKickofMethodClick()
{
MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, kickoffMethod, protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, kickoffMethod, protocol: "metadata")));
}
string kickoffMethodTooltip;

2
ILSpy/Metadata/GoToTokenCommand.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.Commands @@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.Commands
public void Execute(TextViewContext context)
{
int token = GetSelectedToken(context.DataGrid, out MetadataFile module).Value;
MainWindow.Instance.JumpToReference(new EntityReference(module, MetadataTokens.Handle(token), protocol: "metadata"));
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(module, MetadataTokens.Handle(token), protocol: "metadata")));
}
public bool IsEnabled(TextViewContext context)

2
ILSpy/Metadata/MetadataProtocolHandler.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -34,7 +34,7 @@ namespace ICSharpCode.ILSpy.Metadata
newTabPage = true;
if (protocol != "metadata")
return null;
var assemblyTreeNode = MainWindow.Instance.FindTreeNode(module) as AssemblyTreeNode;
var assemblyTreeNode = MainWindow.Instance.AssemblyTreeModel.FindTreeNode(module) as AssemblyTreeNode;
if (assemblyTreeNode == null)
return null;
var mxNode = assemblyTreeNode.Children.OfType<MetadataTreeNode>().FirstOrDefault();

1
ILSpy/Metadata/MetadataTablesTreeNode.cs

@ -23,7 +23,6 @@ using System.Reflection.Metadata.Ecma335; @@ -23,7 +23,6 @@ using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata

1
ILSpy/Options/DecompilerSettingsPanel.xaml.cs

@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
using System.ComponentModel.Composition;
using System.Xml.Linq;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.Settings;
namespace ICSharpCode.ILSpy.Options

1
ILSpy/Options/DisplaySettingsPanel.xaml.cs

@ -27,7 +27,6 @@ using System.Windows.Media; @@ -27,7 +27,6 @@ using System.Windows.Media;
using System.Windows.Threading;
using System.Xml.Linq;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.Settings;
namespace ICSharpCode.ILSpy.Options

7
ILSpy/Search/SearchPane.xaml.cs

@ -32,7 +32,6 @@ using System.Windows.Media; @@ -32,7 +32,6 @@ using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Extensions;
@ -250,8 +249,8 @@ namespace ICSharpCode.ILSpy.Search @@ -250,8 +249,8 @@ namespace ICSharpCode.ILSpy.Search
{
searchProgressBar.IsIndeterminate = true;
startedSearch = new(await mainWindow.CurrentAssemblyList.GetAllAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage,
startedSearch = new(await mainWindow.AssemblyTreeModel.CurrentAssemblyList.GetAllAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.AssemblyTreeModel.CurrentLanguage,
SettingsService.Instance.SessionSettings.LanguageSettings.ShowApiLevel);
currentSearch = startedSearch;
@ -269,7 +268,7 @@ namespace ICSharpCode.ILSpy.Search @@ -269,7 +268,7 @@ namespace ICSharpCode.ILSpy.Search
{
if (listBox.SelectedItem is SearchResult result)
{
MainWindow.Instance.JumpToReference(result.Reference);
MessageBus.Send(this, new NavigateToReferenceEventArgs(result.Reference));
}
}

1
ILSpy/Search/SearchPaneModel.cs

@ -20,7 +20,6 @@ using System.ComponentModel.Composition; @@ -20,7 +20,6 @@ using System.ComponentModel.Composition;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX.Search;

1
ILSpy/SessionSettings.cs

@ -28,7 +28,6 @@ using System.Xml.Linq; @@ -28,7 +28,6 @@ using System.Xml.Linq;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Themes;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.Search;
using ICSharpCode.ILSpyX.Settings;

2
ILSpy/TaskHelper.cs

@ -198,7 +198,7 @@ namespace ICSharpCode.ILSpy @@ -198,7 +198,7 @@ namespace ICSharpCode.ILSpy
public static void HandleExceptions(this Task task)
{
task.Catch<Exception>(exception => MainWindow.Instance.Dispatcher.BeginInvoke(new Action(delegate {
AvalonEditTextOutput output = new AvalonEditTextOutput();
AvalonEditTextOutput output = new();
output.Write(exception.ToString());
Docking.DockWorkspace.Instance.ShowText(output);
}))).IgnoreExceptions();

8
ILSpy/TextView/DecompilerTextView.cs

@ -52,11 +52,11 @@ using ICSharpCode.Decompiler.CSharp.OutputVisitor; @@ -52,11 +52,11 @@ using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.AvalonEdit;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.Themes;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
@ -414,7 +414,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -414,7 +414,7 @@ namespace ICSharpCode.ILSpy.TextView
}
else if (segment.Reference is EntityReference unresolvedEntity)
{
var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.CurrentAssemblyList);
var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList);
if (module == null)
return null;
var typeSystem = new DecompilerTypeSystem(module,
@ -474,7 +474,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -474,7 +474,7 @@ namespace ICSharpCode.ILSpy.TextView
IEntity? ResolveReference(string idString)
{
return MainWindow.FindEntityInRelevantAssemblies(idString, MainWindow.Instance.CurrentAssemblyList.GetAssemblies());
return AssemblyListPaneModel.FindEntityInRelevantAssemblies(idString, MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.GetAssemblies());
}
}
@ -1001,7 +1001,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -1001,7 +1001,7 @@ namespace ICSharpCode.ILSpy.TextView
return;
}
}
MainWindow.Instance.JumpToReference(reference, openInNewTab);
MessageBus.Send(this, new NavigateToReferenceEventArgs(reference, openInNewTab));
}
Point? mouseDownPos;

5
ILSpy/TextView/DocumentationUIBuilder.cs

@ -37,7 +37,6 @@ using ICSharpCode.Decompiler.Documentation; @@ -37,7 +37,6 @@ using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.Output;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.Util;
namespace ICSharpCode.ILSpy.TextView
{
@ -339,7 +338,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -339,7 +338,7 @@ namespace ICSharpCode.ILSpy.TextView
{
var h = new Hyperlink(new Run(ambience.ConvertSymbol(referencedEntity)));
h.Click += (sender, e) => {
MainWindow.Instance.JumpToReference(referencedEntity);
MessageBus.Send(this, new NavigateToReferenceEventArgs(referencedEntity));
};
return h;
}
@ -382,7 +381,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -382,7 +381,7 @@ namespace ICSharpCode.ILSpy.TextView
{
Hyperlink link = new Hyperlink();
link.Click += (sender, e) => {
MainWindow.Instance.JumpToReference(referencedEntity);
MessageBus.Send(this, new NavigateToReferenceEventArgs(referencedEntity));
};
AddSpan(link, element.Children);
}

1
ILSpy/Themes/WindowStyleManagerBehavior.cs

@ -24,7 +24,6 @@ using System.Windows.Interop; @@ -24,7 +24,6 @@ using System.Windows.Interop;
using System.Windows.Media;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.Util;
using TomsToolbox.Essentials;
using TomsToolbox.Wpf;

18
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -24,10 +24,9 @@ using System.Windows; @@ -24,10 +24,9 @@ using System.Windows;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
using ICSharpCode.ILSpyX.TreeView;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -87,13 +86,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -87,13 +86,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
e.Effects = XPlatDragDropEffects.Move | XPlatDragDropEffects.Copy | XPlatDragDropEffects.Link;
if (e.Data.GetDataPresent(AssemblyTreeNode.DataFormat))
return true;
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
if (e.Data.GetDataPresent(DataFormats.FileDrop))
return true;
else
{
e.Effects = XPlatDragDropEffects.None;
return false;
}
e.Effects = XPlatDragDropEffects.None;
return false;
}
public override void Drop(IPlatformDragEventArgs e, int index)
@ -110,8 +106,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -110,8 +106,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
.Distinct()
.ToArray();
assemblyList.Move(assemblies, index);
var nodes = assemblies.SelectArray(MainWindow.Instance.FindTreeNode);
MainWindow.Instance.SelectNodes(nodes);
var nodes = assemblies.SelectArray(MainWindow.Instance.AssemblyTreeModel.FindTreeNode);
MainWindow.Instance.AssemblyTreeModel.SelectNodes(nodes);
}
}
@ -187,7 +183,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -187,7 +183,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (bundle == null)
return null;
bundle.EnsureLazyChildren();
foreach (var node in ILSpyX.TreeView.TreeTraversal.PreOrder(bundle.Children, ExpandAndGetChildren).OfType<AssemblyTreeNode>())
foreach (var node in TreeTraversal.PreOrder(bundle.Children, ExpandAndGetChildren).OfType<AssemblyTreeNode>())
{
if (node.LoadedAssembly == asm)
return node;

1
ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

@ -26,7 +26,6 @@ using ICSharpCode.Decompiler; @@ -26,7 +26,6 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Themes;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
namespace ICSharpCode.ILSpy.TreeNodes

12
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -30,10 +30,10 @@ using ICSharpCode.Decompiler; @@ -30,10 +30,10 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Controls.TreeView;
using ICSharpCode.ILSpy.Metadata;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.FileLoaders;
@ -630,13 +630,13 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -630,13 +630,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
foreach (var node in context.SelectedTreeNodes)
{
paths.Add(MainWindow.GetPathForNode(node));
paths.Add(AssemblyListPaneModel.GetPathForNode(node));
var la = ((AssemblyTreeNode)node).LoadedAssembly;
la.AssemblyList.ReloadAssembly(la.FileName);
}
}
MainWindow.Instance.SelectNodes(paths.Select(p => MainWindow.Instance.FindNodeByPath(p, true)).ToArray());
MainWindow.Instance.RefreshDecompiledView();
MainWindow.Instance.AssemblyTreeModel.SelectNodes(paths.Select(p => MainWindow.Instance.AssemblyTreeModel.FindNodeByPath(p, true)).ToArray());
MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView();
}
}
@ -676,7 +676,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -676,7 +676,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
await Task.WhenAll(tasks);
MainWindow.Instance.RefreshDecompiledView();
MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView();
}
}
@ -711,7 +711,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -711,7 +711,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
node.RaisePropertyChanged(nameof(ILSpyTreeNode.IsAutoLoaded));
}
}
MainWindow.Instance.CurrentAssemblyList.RefreshSave();
MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.RefreshSave();
}
}

5
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -27,7 +27,6 @@ using System.Windows.Threading; @@ -27,7 +27,6 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.Abstractions;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
using ICSharpCode.ILSpyX.TreeView;
@ -72,8 +71,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -72,8 +71,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void ActivateItemSecondary(IPlatformRoutedEventArgs e)
{
MainWindow.Instance.SelectNode(this, inNewTabPage: true);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView);
MainWindow.Instance.AssemblyTreeModel.SelectNode(this, inNewTabPage: true);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView);
}
/// <summary>

9
ILSpy/Util/MessageBus.cs

@ -57,4 +57,13 @@ namespace ICSharpCode.ILSpy.Util @@ -57,4 +57,13 @@ namespace ICSharpCode.ILSpy.Util
public class SessionSettingsChangedEventArgs(PropertyChangedEventArgs e) : WrappedEventArgs<PropertyChangedEventArgs>(e);
public class DockWorkspaceActiveTabPageChangedEventArgs : EventArgs;
public class NavigateToReferenceEventArgs(object reference, bool inNewTabPage = false) : EventArgs
{
public object Reference { get; } = reference;
public bool InNewTabPage { get; } = inNewTabPage;
}
public class AssemblyTreeSelectionChangedEventArgs() : EventArgs;
}

48
ILSpy/Util/NavigationHistoryService.cs

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
using System;
namespace ICSharpCode.ILSpy.Util
{
public class NavigationHistoryService
{
readonly NavigationHistory<NavigationState> history = new();
public static NavigationHistoryService Instance { get; } = new();
public bool CanNavigateBack => history.CanNavigateBack;
public bool CanNavigateForward => history.CanNavigateForward;
private NavigationHistoryService()
{
}
public void UpdateCurrent(NavigationState navigationState)
{
history.UpdateCurrent(navigationState);
}
public void Record(NavigationState navigationState)
{
history.Record(navigationState);
}
public NavigationState GoForward()
{
return history.GoForward();
}
public NavigationState GoBack()
{
return history.GoBack();
}
public void Clear()
{
history.Clear();
}
public void RemoveAll(Predicate<NavigationState> predicate)
{
history.RemoveAll(predicate);
}
}
}

41
ILSpy/ViewModels/AssemblyListPaneModel.cs

@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy.ViewModels
{
[ExportToolPane]
[PartCreationPolicy(CreationPolicy.Shared)]
public class AssemblyListPaneModel : ToolPaneModel
{
public const string PaneContentId = "assemblyListPane";
public AssemblyListPaneModel()
{
Title = Resources.Assemblies;
ContentId = PaneContentId;
IsCloseable = false;
ShortcutKey = new KeyGesture(Key.F6);
}
}
}

1
ILSpy/ViewModels/ManageAssemblyListsViewModel.cs

@ -27,7 +27,6 @@ using System.Windows.Input; @@ -27,7 +27,6 @@ using System.Windows.Input;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Commands;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy.ViewModels

14
ILSpy/ViewModels/PaneModel.cs

@ -21,7 +21,7 @@ using System.ComponentModel; @@ -21,7 +21,7 @@ using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.Decompiler.IL;
using TomsToolbox.Wpf;
@ -29,6 +29,13 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -29,6 +29,13 @@ namespace ICSharpCode.ILSpy.ViewModels
{
public abstract class PaneModel : ObservableObject
{
private Throttle titleChangeThrottle;
protected PaneModel()
{
titleChangeThrottle = new Throttle(() => OnPropertyChanged(nameof(Title)));
}
class CloseCommandImpl : ICommand
{
readonly PaneModel model;
@ -107,7 +114,10 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -107,7 +114,10 @@ namespace ICSharpCode.ILSpy.ViewModels
public string Title {
get => title;
set => SetProperty(ref title, value);
set {
title = value;
titleChangeThrottle.Tick();
}
}
}

2
ILSpy/ViewModels/TabPageModel.cs

@ -20,8 +20,6 @@ using System; @@ -20,8 +20,6 @@ using System;
using System.Threading.Tasks;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy.ViewModels
{

9
ILSpy/Views/DebugSteps.xaml.cs

@ -8,7 +8,6 @@ using System.Windows.Input; @@ -8,7 +8,6 @@ using System.Windows.Input;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using TomsToolbox.Wpf.Composition.Mef;
@ -35,8 +34,8 @@ namespace ICSharpCode.ILSpy @@ -35,8 +34,8 @@ namespace ICSharpCode.ILSpy
#if DEBUG
MessageBus<LanguageSettingsChangedEventArgs>.Subscribers += (sender, e) => LanguageSettings_PropertyChanged(sender, e);
MessageBus<AssemblyTreeSelectionChangedEventArgs>.Subscribers += SelectionChanged;
MainWindow.Instance.SelectionChanged += SelectionChanged;
writingOptions.PropertyChanged += WritingOptions_PropertyChanged;
if (SettingsService.Instance.SessionSettings.LanguageSettings.Language is ILAstLanguage l)
@ -53,7 +52,7 @@ namespace ICSharpCode.ILSpy @@ -53,7 +52,7 @@ namespace ICSharpCode.ILSpy
DecompileAsync(lastSelectedStep);
}
private void SelectionChanged(object sender, SelectionChangedEventArgs e)
private void SelectionChanged(object sender, EventArgs e)
{
Dispatcher.Invoke(() => {
tree.ItemsSource = null;
@ -123,8 +122,8 @@ namespace ICSharpCode.ILSpy @@ -123,8 +122,8 @@ namespace ICSharpCode.ILSpy
lastSelectedStep = step;
var window = MainWindow.Instance;
var state = DockWorkspace.Instance.ActiveTabPage.GetState();
DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(window.CurrentLanguage, window.SelectedNodes,
new DecompilationOptions(window.CurrentLanguageVersion, SettingsService.Instance.DecompilerSettings, SettingsService.Instance.DisplaySettings) {
DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(window.AssemblyTreeModel.CurrentLanguage, window.AssemblyTreeModel.SelectedNodes,
new DecompilationOptions(window.AssemblyTreeModel.CurrentLanguageVersion, SettingsService.Instance.DecompilerSettings, SettingsService.Instance.DisplaySettings) {
StepLimit = step,
IsDebug = isDebug,
TextViewState = state as TextView.DecompilerTextViewState

2
TestPlugin/MainMenuCommand.cs

@ -23,7 +23,7 @@ namespace TestPlugin @@ -23,7 +23,7 @@ namespace TestPlugin
{
public override void Execute(object parameter)
{
foreach (var loadedAssembly in MainWindow.Instance.CurrentAssemblyList.GetAssemblies())
foreach (var loadedAssembly in MainWindow.Instance.AssemblyTreeModel.CurrentAssemblyList.GetAssemblies())
{
loadedAssembly.AssemblyList.Unload(loadedAssembly);
}

Loading…
Cancel
Save