diff --git a/ILSpy/App.xaml.cs b/ILSpy/App.xaml.cs index 05c077751..f437811cf 100644 --- a/ILSpy/App.xaml.cs +++ b/ILSpy/App.xaml.cs @@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy if (!InitializeDependencyInjection(settingsService)) { // There is something completely wrong with DI, probably some service registration is missing => nothing we can do to recover, so stop and shut down. - Exit += (_, _) => MessageBox.Show(StartupExceptions.FormatExceptions(), "Sorry we crashed!"); + Exit += (_, _) => MessageBox.Show(StartupExceptions.FormatExceptions(), "Sorry we crashed!", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); Shutdown(1); return; } diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index 59d3ba47e..bf46861d9 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -264,7 +264,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree { AvalonEditTextOutput output = new AvalonEditTextOutput(); output.Write($"Cannot find '{navigateTo}' in command line specified assemblies."); - DockWorkspace.Instance.ShowText(output); + DockWorkspace.ShowText(output); } } else if (relevantAssemblies.Count == 1) @@ -304,7 +304,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree } else { - DockWorkspace.Instance.ActiveTabPage.ShowTextView(aboutPage.Display); + DockWorkspace.ActiveTabPage.ShowTextView(aboutPage.Display); } } } @@ -405,8 +405,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree { output.Title = "Startup errors"; - DockWorkspace.Instance.AddTabPage(); - DockWorkspace.Instance.ShowText(output); + DockWorkspace.AddTabPage(); + DockWorkspace.ShowText(output); } } @@ -524,7 +524,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree if (inNewTabPage) { - DockWorkspace.Instance.AddTabPage(); + DockWorkspace.AddTabPage(); SelectedItem = null; } @@ -739,7 +739,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree } else { - var activeTabPage = DockWorkspace.Instance.ActiveTabPage; + var activeTabPage = DockWorkspace.ActiveTabPage; if (!isNavigatingHistory) { @@ -787,7 +787,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree public void DecompileSelectedNodes(DecompilerTextViewState? newState = null) { - var activeTabPage = DockWorkspace.Instance.ActiveTabPage; + var activeTabPage = DockWorkspace.ActiveTabPage; activeTabPage.SupportsLanguageSwitching = true; @@ -809,7 +809,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree public void RefreshDecompiledView() { - DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState); + DecompileSelectedNodes(DockWorkspace.ActiveTabPage.GetState() as DecompilerTextViewState); } public Language CurrentLanguage => languageService.Language; @@ -830,7 +830,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree { isNavigatingHistory = true; - TabPageModel tabPage = DockWorkspace.Instance.ActiveTabPage; + TabPageModel tabPage = DockWorkspace.ActiveTabPage; var state = tabPage.GetState(); if (state != null) history.UpdateCurrent(new NavigationState(tabPage, state)); @@ -838,10 +838,10 @@ namespace ICSharpCode.ILSpy.AssemblyTree TabPageModel activeTabPage = newState.TabPage; - if (!DockWorkspace.Instance.TabPages.Contains(activeTabPage)) - DockWorkspace.Instance.AddTabPage(activeTabPage); + if (!DockWorkspace.TabPages.Contains(activeTabPage)) + DockWorkspace.AddTabPage(activeTabPage); else - DockWorkspace.Instance.ActiveTabPage = activeTabPage; + DockWorkspace.ActiveTabPage = activeTabPage; SelectNodes(newState.TreeNodes); } @@ -861,13 +861,13 @@ namespace ICSharpCode.ILSpy.AssemblyTree { if (inNewTabPage) { - DockWorkspace.Instance.AddTabPage(); + DockWorkspace.AddTabPage(); } if (e.Uri.Host == "aboutpage") { RecordHistory(); - DockWorkspace.Instance.ActiveTabPage.ShowTextView(aboutPage.Display); + DockWorkspace.ActiveTabPage.ShowTextView(aboutPage.Display); e.Handled = true; return; } @@ -891,7 +891,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree } } RecordHistory(); - DockWorkspace.Instance.ShowText(output); + DockWorkspace.ShowText(output); e.Handled = true; } @@ -899,7 +899,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree { if (isNavigatingHistory) return; - TabPageModel tabPage = DockWorkspace.Instance.ActiveTabPage; + TabPageModel tabPage = DockWorkspace.ActiveTabPage; var currentState = tabPage.GetState(); if (currentState != null) history.UpdateCurrent(new NavigationState(tabPage, currentState)); diff --git a/ILSpy/Commands/DecompileAllCommand.cs b/ILSpy/Commands/DecompileAllCommand.cs index 06c093a44..7a9bebf18 100644 --- a/ILSpy/Commands/DecompileAllCommand.cs +++ b/ILSpy/Commands/DecompileAllCommand.cs @@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy { [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)] [Shared] - sealed class DecompileAllCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand + sealed class DecompileAllCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand { public override bool CanExecute(object parameter) { @@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy public override void Execute(object parameter) { - Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task.Factory.StartNew(() => { + dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { AvalonEditTextOutput output = new AvalonEditTextOutput(); Parallel.ForEach( Partitioner.Create(assemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true), @@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy { try { - var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions(); + var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions(); options.CancellationToken = ct; options.FullDecompilation = true; new CSharpLanguage().DecompileAssembly(asm, new PlainTextOutput(writer), options); @@ -85,20 +85,19 @@ namespace ICSharpCode.ILSpy } }); return output; - }, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions(); + }, ct)).Then(dockWorkspace.ShowText).HandleExceptions(); } } [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile100x), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)] [Shared] - sealed class Decompile100TimesCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand + sealed class Decompile100TimesCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : SimpleCommand { public override void Execute(object parameter) { const int numRuns = 100; var language = languageService.Language; var nodes = assemblyTreeModel.SelectedNodes.ToArray(); - DockWorkspace dockWorkspace = DockWorkspace.Instance; var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions(); dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { options.CancellationToken = ct; diff --git a/ILSpy/Commands/DecompileInNewViewCommand.cs b/ILSpy/Commands/DecompileInNewViewCommand.cs index 107a11b46..3601517b0 100644 --- a/ILSpy/Commands/DecompileInNewViewCommand.cs +++ b/ILSpy/Commands/DecompileInNewViewCommand.cs @@ -35,15 +35,8 @@ namespace ICSharpCode.ILSpy.Commands { [ExportContextMenuEntry(Header = nameof(Resources.DecompileToNewPanel), InputGestureText = "MMB", Icon = "images/Search", Category = nameof(Resources.Analyze), Order = 90)] [Shared] - internal sealed class DecompileInNewViewCommand : IContextMenuEntry + internal sealed class DecompileInNewViewCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : IContextMenuEntry { - private readonly AssemblyTreeModel assemblyTreeModel; - - public DecompileInNewViewCommand(AssemblyTreeModel assemblyTreeModel) - { - this.assemblyTreeModel = assemblyTreeModel; - } - public bool IsVisible(TextViewContext context) { return context.SelectedTreeNodes != null || context.Reference?.Reference is IEntity; @@ -56,11 +49,11 @@ namespace ICSharpCode.ILSpy.Commands public void Execute(TextViewContext context) { - var activePane = DockWorkspace.Instance.ActivePane; + var activePane = dockWorkspace.ActivePane; DecompileNodes(GetNodes(context).ToArray()); - DockWorkspace.Instance.ActivePane = activePane; + dockWorkspace.ActivePane = activePane; } IEnumerable GetNodes(TextViewContext context) @@ -98,7 +91,7 @@ namespace ICSharpCode.ILSpy.Commands if (nodes.Length == 0) return; - DockWorkspace.Instance.AddTabPage(); + dockWorkspace.AddTabPage(); if (assemblyTreeModel.SelectedItems.SequenceEqual(nodes)) assemblyTreeModel.DecompileSelectedNodes(); diff --git a/ILSpy/Commands/DisassembleAllCommand.cs b/ILSpy/Commands/DisassembleAllCommand.cs index 8b81e87b2..26682b9d1 100644 --- a/ILSpy/Commands/DisassembleAllCommand.cs +++ b/ILSpy/Commands/DisassembleAllCommand.cs @@ -25,6 +25,7 @@ using System.Diagnostics; using System.Threading.Tasks; using ICSharpCode.ILSpy.AssemblyTree; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; @@ -33,7 +34,7 @@ namespace ICSharpCode.ILSpy { [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDisassemble), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)] [Shared] - sealed class DisassembleAllCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand + sealed class DisassembleAllCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand { public override bool CanExecute(object parameter) { @@ -42,8 +43,6 @@ namespace ICSharpCode.ILSpy public override void Execute(object parameter) { - var dockWorkspace = Docking.DockWorkspace.Instance; - dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { AvalonEditTextOutput output = new(); Parallel.ForEach( @@ -61,7 +60,7 @@ namespace ICSharpCode.ILSpy var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions(); options.FullDecompilation = true; options.CancellationToken = ct; - new ILLanguage().DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), options); + new ILLanguage(dockWorkspace).DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), options); } catch (Exception ex) { diff --git a/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs b/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs index 2d558aca4..cf715759d 100644 --- a/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs +++ b/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs @@ -25,6 +25,7 @@ using System.Threading.Tasks; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; @@ -36,7 +37,7 @@ namespace ICSharpCode.ILSpy { [ExportContextMenuEntry(Header = nameof(Resources.ExtractPackageEntry), Category = nameof(Resources.Save), Icon = "Images/Save")] [Shared] - sealed class ExtractPackageEntryContextMenuEntry : IContextMenuEntry + sealed class ExtractPackageEntryContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry { public void Execute(TextViewContext context) { @@ -61,7 +62,7 @@ namespace ICSharpCode.ILSpy if (selectedNodes.Length > 1) outputFolderOrFileName = Path.GetDirectoryName(outputFolderOrFileName); - Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task.Factory.StartNew(() => { + dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { AvalonEditTextOutput output = new AvalonEditTextOutput(); Stopwatch stopwatch = Stopwatch.StartNew(); stopwatch.Stop(); @@ -83,7 +84,7 @@ namespace ICSharpCode.ILSpy output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); }); output.WriteLine(); return output; - }, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions(); + }, ct)).Then(dockWorkspace.ShowText).HandleExceptions(); } void SaveEntry(ITextOutput output, PackageEntry entry, string targetFileName) diff --git a/ILSpy/Commands/GeneratePdbContextMenuEntry.cs b/ILSpy/Commands/GeneratePdbContextMenuEntry.cs index 63f38d95f..7a0374895 100644 --- a/ILSpy/Commands/GeneratePdbContextMenuEntry.cs +++ b/ILSpy/Commands/GeneratePdbContextMenuEntry.cs @@ -43,14 +43,14 @@ namespace ICSharpCode.ILSpy { [ExportContextMenuEntry(Header = nameof(Resources.GeneratePortable))] [Shared] - class GeneratePdbContextMenuEntry(LanguageService languageService) : IContextMenuEntry + class GeneratePdbContextMenuEntry(LanguageService languageService, DockWorkspace dockWorkspace) : IContextMenuEntry { public void Execute(TextViewContext context) { var assembly = (context.SelectedTreeNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly; if (assembly == null) return; - GeneratePdbForAssembly(assembly, languageService); + GeneratePdbForAssembly(assembly, languageService, dockWorkspace); } public bool IsEnabled(TextViewContext context) => true; @@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpy && tn.LoadedAssembly.IsLoadedAsValidAssembly; } - internal static void GeneratePdbForAssembly(LoadedAssembly assembly, LanguageService languageService) + internal static void GeneratePdbForAssembly(LoadedAssembly assembly, LanguageService languageService, DockWorkspace dockWorkspace) { var file = assembly.GetMetadataFileOrNull() as PEFile; if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file)) @@ -76,7 +76,6 @@ namespace ICSharpCode.ILSpy dlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName); if (dlg.ShowDialog() != true) return; - DockWorkspace dockWorkspace = DockWorkspace.Instance; DecompilationOptions options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions(); string fileName = dlg.FileName; dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { @@ -104,13 +103,13 @@ namespace ICSharpCode.ILSpy output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); }); output.WriteLine(); return output; - }, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions(); + }, ct)).Then(dockWorkspace.ShowText).HandleExceptions(); } } [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.GeneratePortable), MenuCategory = nameof(Resources.Save))] [Shared] - class GeneratePdbMainMenuEntry(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand + class GeneratePdbMainMenuEntry(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : SimpleCommand { public override bool CanExecute(object parameter) { @@ -124,7 +123,7 @@ namespace ICSharpCode.ILSpy var assembly = (assemblyTreeModel.SelectedNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly; if (assembly == null) return; - GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly, languageService); + GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly, languageService, dockWorkspace); } } } diff --git a/ILSpy/Commands/Pdb2XmlCommand.cs b/ILSpy/Commands/Pdb2XmlCommand.cs index 14cfbeabe..13de31ee5 100644 --- a/ILSpy/Commands/Pdb2XmlCommand.cs +++ b/ILSpy/Commands/Pdb2XmlCommand.cs @@ -27,6 +27,7 @@ using System.Threading.Tasks; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.Decompiler; using ICSharpCode.ILSpy.AssemblyTree; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; @@ -37,7 +38,7 @@ namespace ICSharpCode.ILSpy { [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDumpPDBAsXML), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)] [Shared] - sealed class Pdb2XmlCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand + sealed class Pdb2XmlCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand { public override bool CanExecute(object parameter) { @@ -48,14 +49,14 @@ namespace ICSharpCode.ILSpy public override void Execute(object parameter) { - Execute(assemblyTreeModel.SelectedNodes.OfType()); + Execute(assemblyTreeModel.SelectedNodes.OfType(), dockWorkspace); } - internal static void Execute(IEnumerable nodes) + internal static void Execute(IEnumerable nodes, DockWorkspace dockWorkspace) { var highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml"); var options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.IncludeMethodSpans | PdbToXmlOptions.IncludeTokens; - Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task.Factory.StartNew(() => { + dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { AvalonEditTextOutput output = new AvalonEditTextOutput(); var writer = new TextOutputWriter(output); foreach (var node in nodes) @@ -68,17 +69,17 @@ namespace ICSharpCode.ILSpy PdbToXmlConverter.ToXml(writer, pdbStream, peStream, options); } return output; - }, ct)).Then(output => Docking.DockWorkspace.Instance.ShowNodes(output, null, highlighting)).HandleExceptions(); + }, ct)).Then(output => dockWorkspace.ShowNodes(output, null, highlighting)).HandleExceptions(); } } [ExportContextMenuEntry(Header = nameof(Resources.DEBUGDumpPDBAsXML))] [Shared] - class Pdb2XmlCommandContextMenuEntry : IContextMenuEntry + class Pdb2XmlCommandContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry { public void Execute(TextViewContext context) { - Pdb2XmlCommand.Execute(context.SelectedTreeNodes.OfType()); + Pdb2XmlCommand.Execute(context.SelectedTreeNodes.OfType(), dockWorkspace); } public bool IsEnabled(TextViewContext context) => true; diff --git a/ILSpy/Commands/SaveCodeContextMenuEntry.cs b/ILSpy/Commands/SaveCodeContextMenuEntry.cs index 2dd646450..071f29599 100644 --- a/ILSpy/Commands/SaveCodeContextMenuEntry.cs +++ b/ILSpy/Commands/SaveCodeContextMenuEntry.cs @@ -23,6 +23,7 @@ using System.IO; using System.Linq; using System.Windows; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.ViewModels; @@ -35,11 +36,11 @@ namespace ICSharpCode.ILSpy.TextView { [ExportContextMenuEntry(Header = nameof(Resources._SaveCode), Category = nameof(Resources.Save), Icon = "Images/Save")] [Shared] - sealed class SaveCodeContextMenuEntry(LanguageService languageService) : IContextMenuEntry + sealed class SaveCodeContextMenuEntry(LanguageService languageService, DockWorkspace dockWorkspace) : IContextMenuEntry { public void Execute(TextViewContext context) { - Execute(context.SelectedTreeNodes, languageService); + Execute(context.SelectedTreeNodes, languageService, dockWorkspace); } public bool IsEnabled(TextViewContext context) => true; @@ -57,10 +58,8 @@ namespace ICSharpCode.ILSpy.TextView || (selectedNodes.Count > 1 && (selectedNodes.All(n => n is AssemblyTreeNode) || selectedNodes.All(n => n is IMemberTreeNode))); } - public static void Execute(IReadOnlyList selectedNodes, LanguageService languageService) + public static void Execute(IReadOnlyList selectedNodes, LanguageService languageService, DockWorkspace dockWorkspace) { - var dockWorkspace = Docking.DockWorkspace.Instance; - var currentLanguage = languageService.Language; var tabPage = dockWorkspace.ActiveTabPage; tabPage.ShowTextView(textView => { @@ -80,7 +79,7 @@ namespace ICSharpCode.ILSpy.TextView var assemblies = selectedNodes.OfType() .Select(n => n.LoadedAssembly) .Where(a => a.IsLoadedAsValidAssembly).ToArray(); - SolutionWriter.CreateSolution(textView, selectedPath, currentLanguage, assemblies); + SolutionWriter.CreateSolution(tabPage, textView, selectedPath, currentLanguage, assemblies); } return; } diff --git a/ILSpy/Commands/SaveCommand.cs b/ILSpy/Commands/SaveCommand.cs index 3281df456..ae5ca6505 100644 --- a/ILSpy/Commands/SaveCommand.cs +++ b/ILSpy/Commands/SaveCommand.cs @@ -21,6 +21,7 @@ using System.Linq; using System.Windows.Input; using ICSharpCode.ILSpy.AssemblyTree; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; @@ -28,7 +29,7 @@ namespace ICSharpCode.ILSpy { [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._SaveCode), MenuIcon = "Images/Save", MenuCategory = nameof(Resources.Save), MenuOrder = 0)] [Shared] - sealed class SaveCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : CommandWrapper(ApplicationCommands.Save) + sealed class SaveCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : CommandWrapper(ApplicationCommands.Save) { protected override void OnCanExecute(object sender, CanExecuteRoutedEventArgs e) { @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy protected override void OnExecute(object sender, ExecutedRoutedEventArgs e) { - SaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList(), languageService); + SaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList(), languageService, dockWorkspace); } } } diff --git a/ILSpy/Commands/ShowPane.cs b/ILSpy/Commands/ShowPane.cs index 1c6694bd9..5d13f57ce 100644 --- a/ILSpy/Commands/ShowPane.cs +++ b/ILSpy/Commands/ShowPane.cs @@ -3,39 +3,23 @@ using ICSharpCode.ILSpy.ViewModels; namespace ICSharpCode.ILSpy.Commands { - class ToolPaneCommand : SimpleCommand + class ToolPaneCommand(string contentId, DockWorkspace dockWorkspace) : SimpleCommand { - readonly string contentId; - - public ToolPaneCommand(string contentId) - { - this.contentId = contentId; - } - public override void Execute(object parameter) { - DockWorkspace.Instance.ShowToolPane(contentId); + dockWorkspace.ShowToolPane(contentId); } } - class TabPageCommand : SimpleCommand + class TabPageCommand(TabPageModel model, DockWorkspace dockWorkspace) : SimpleCommand { - readonly TabPageModel model; - - public TabPageCommand(TabPageModel model) - { - this.model = model; - } - public override void Execute(object parameter) { - var workspace = DockWorkspace.Instance; - // ensure the tab control is focused before setting the active tab page, else the tab will not be focused - workspace.ActiveTabPage?.Focus(); + dockWorkspace.ActiveTabPage?.Focus(); // reset first, else clicking on the already active tab will not focus the tab and the menu checkmark will not be updated - workspace.ActiveTabPage = null; - workspace.ActiveTabPage = model; + dockWorkspace.ActiveTabPage = null; + dockWorkspace.ActiveTabPage = model; } } } \ No newline at end of file diff --git a/ILSpy/Controls/ZoomScrollViewer.cs b/ILSpy/Controls/ZoomScrollViewer.cs index 21e258963..7c14528cb 100644 --- a/ILSpy/Controls/ZoomScrollViewer.cs +++ b/ILSpy/Controls/ZoomScrollViewer.cs @@ -176,21 +176,4 @@ namespace ICSharpCode.ILSpy.Controls return val; } } - - sealed class IsNormalZoomConverter : IValueConverter - { - public static readonly IsNormalZoomConverter Instance = new IsNormalZoomConverter(); - - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (parameter is bool && (bool)parameter) - return true; - return ((double)value) == 1.0; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } } diff --git a/ILSpy/Docking/CloseAllDocumentsCommand.cs b/ILSpy/Docking/CloseAllDocumentsCommand.cs index c41f59943..b7f05e50f 100644 --- a/ILSpy/Docking/CloseAllDocumentsCommand.cs +++ b/ILSpy/Docking/CloseAllDocumentsCommand.cs @@ -6,21 +6,21 @@ namespace ICSharpCode.ILSpy.Docking { [ExportMainMenuCommand(Header = nameof(Resources.Window_CloseAllDocuments), ParentMenuID = nameof(Resources._Window))] [Shared] - class CloseAllDocumentsCommand : SimpleCommand + class CloseAllDocumentsCommand(DockWorkspace dockWorkspace) : SimpleCommand { public override void Execute(object parameter) { - DockWorkspace.Instance.CloseAllTabs(); + dockWorkspace.CloseAllTabs(); } } [ExportMainMenuCommand(Header = nameof(Resources.Window_ResetLayout), ParentMenuID = nameof(Resources._Window))] [Shared] - class ResetLayoutCommand : SimpleCommand + class ResetLayoutCommand(DockWorkspace dockWorkspace) : SimpleCommand { public override void Execute(object parameter) { - DockWorkspace.Instance.ResetLayout(); + dockWorkspace.ResetLayout(); } } } diff --git a/ILSpy/Docking/DockWorkspace.cs b/ILSpy/Docking/DockWorkspace.cs index af59d3f59..938020117 100644 --- a/ILSpy/Docking/DockWorkspace.cs +++ b/ILSpy/Docking/DockWorkspace.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; +using System.Composition; using System.Linq; using System.Reflection; using System.Threading; @@ -43,38 +44,34 @@ using TomsToolbox.Wpf; namespace ICSharpCode.ILSpy.Docking { + [Export] + [Shared] public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy { - private static readonly IExportProvider exportProvider = App.ExportProvider; + private readonly IExportProvider exportProvider; + + private SettingsService SettingsService { get; } - private static SettingsService SettingsService => exportProvider.GetExportedValue(); + private LanguageService LanguageService => exportProvider.GetExportedValue(); - private static LanguageService LanguageService => exportProvider.GetExportedValue(); - - private static SessionSettings SessionSettings => SettingsService.SessionSettings; - - public static readonly DockWorkspace Instance = new(); + private SessionSettings SessionSettings { get; } private readonly ObservableCollection tabPages = []; private DockingManager DockingManager => exportProvider.GetExportedValue(); - AssemblyTreeModel AssemblyTreeModel => exportProvider.GetExportedValue(); + private AssemblyTreeModel AssemblyTreeModel => exportProvider.GetExportedValue(); - private DockWorkspace() + public DockWorkspace(SettingsService settingsService, IExportProvider exportProvider) { + this.exportProvider = exportProvider; + + SettingsService = settingsService; + SessionSettings = settingsService.SessionSettings; + this.tabPages.CollectionChanged += TabPages_CollectionChanged; TabPages = new(tabPages); - ToolPanes = exportProvider - .GetExportedValues("ToolPane") - .OrderBy(item => item.Title) - .ToArray() - .AsReadOnly(); - - // Make sure there is at least one tab open - AddTabPage(); - MessageBus.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e); } @@ -135,7 +132,11 @@ namespace ICSharpCode.ILSpy.Docking public ReadOnlyObservableCollection TabPages { get; } - public ReadOnlyCollection ToolPanes { get; } + public ReadOnlyCollection ToolPanes => exportProvider + .GetExportedValues("ToolPane") + .OrderBy(item => item.Title) + .ToArray() + .AsReadOnly(); public bool ShowToolPane(string contentId) { @@ -188,15 +189,15 @@ namespace ICSharpCode.ILSpy.Docking } public PaneModel ActivePane { - get => DockingManager?.ActiveContent as PaneModel; - set { - if (DockingManager is not null) - DockingManager.ActiveContent = value; - } + get => DockingManager.ActiveContent as PaneModel; + set => DockingManager.ActiveContent = value; } public void InitializeLayout() { + // Make sure there is at least one tab open + AddTabPage(); + DockingManager.LayoutUpdateStrategy = this; XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockingManager); serializer.LayoutSerializationCallback += LayoutSerializationCallback; diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 77ec68982..b79b79295 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -34,6 +34,7 @@ using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX.Extensions; @@ -43,7 +44,7 @@ namespace ICSharpCode.ILSpy [Export(typeof(Language))] [Shared] - class CSharpILMixedLanguage(SettingsService settingsService) : ILLanguage + class CSharpILMixedLanguage(SettingsService settingsService, DockWorkspace dockWorkspace) : ILLanguage(dockWorkspace) { public override string Name => "IL with C#"; diff --git a/ILSpy/Languages/ILAstLanguage.cs b/ILSpy/Languages/ILAstLanguage.cs index b0f467b4b..46ccd0fe4 100644 --- a/ILSpy/Languages/ILAstLanguage.cs +++ b/ILSpy/Languages/ILAstLanguage.cs @@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpyX; @@ -41,13 +42,6 @@ namespace ICSharpCode.ILSpy { public event EventHandler StepperUpdated; - protected virtual void OnStepperUpdated(EventArgs e = null) - { - StepperUpdated?.Invoke(this, e ?? new EventArgs()); - } - - public Stepper Stepper { get; set; } = new Stepper(); - readonly string name; protected ILAstLanguage(string name) @@ -55,12 +49,19 @@ namespace ICSharpCode.ILSpy this.name = name; } + protected virtual void OnStepperUpdated(EventArgs e = null) + { + StepperUpdated?.Invoke(this, e ?? new EventArgs()); + } + + public Stepper Stepper { get; set; } = new Stepper(); + public override string Name { get { return name; } } - internal static IEnumerable GetDebugLanguages() + internal static IEnumerable GetDebugLanguages(DockWorkspace dockWorkspace) { yield return new TypedIL(); - yield return new BlockIL(CSharpDecompiler.GetILTransforms()); + yield return new BlockIL(CSharpDecompiler.GetILTransforms(), dockWorkspace); } public override string FileExtension { @@ -78,10 +79,8 @@ namespace ICSharpCode.ILSpy output.WriteLine(); } - class TypedIL : ILAstLanguage + class TypedIL() : ILAstLanguage("Typed IL") { - public TypedIL() : base("Typed IL") { } - public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) { base.DecompileMethod(method, output, options); @@ -96,15 +95,8 @@ namespace ICSharpCode.ILSpy } } - class BlockIL : ILAstLanguage + class BlockIL(IReadOnlyList transforms, DockWorkspace dockWorkspace) : ILAstLanguage("ILAst") { - readonly IReadOnlyList transforms; - - public BlockIL(IReadOnlyList transforms) : base("ILAst") - { - this.transforms = transforms; - } - public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) { base.DecompileMethod(method, output, options); @@ -146,7 +138,7 @@ namespace ICSharpCode.ILSpy } } (output as ISmartTextOutput)?.AddButton(Images.ViewCode, "Show Steps", delegate { - Docking.DockWorkspace.Instance.ShowToolPane(DebugStepsPaneModel.PaneContentId); + dockWorkspace.ShowToolPane(DebugStepsPaneModel.PaneContentId); }); output.WriteLine(); il.WriteTo(output, DebugSteps.Options); diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs index 31494f7d8..ffaa31485 100644 --- a/ILSpy/Languages/ILLanguage.cs +++ b/ILSpy/Languages/ILLanguage.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy /// [Export(typeof(Language))] [Shared] - public class ILLanguage : Language + public class ILLanguage(DockWorkspace dockWorkspace) : Language { protected bool detectControlStructure = true; @@ -199,7 +199,6 @@ namespace ICSharpCode.ILSpy public override RichText GetRichTextTooltip(IEntity entity) { var output = new AvalonEditTextOutput() { IgnoreNewLineAndIndent = true }; - var dockWorkspace = DockWorkspace.Instance; var disasm = CreateDisassembler(output, dockWorkspace.ActiveTabPage.CreateDecompilationOptions()); MetadataFile module = entity.ParentModule?.MetadataFile; diff --git a/ILSpy/Languages/LanguageService.cs b/ILSpy/Languages/LanguageService.cs index f5282853c..6c116b1ad 100644 --- a/ILSpy/Languages/LanguageService.cs +++ b/ILSpy/Languages/LanguageService.cs @@ -24,6 +24,7 @@ using System.Collections.ObjectModel; using System.Composition; using System.Linq; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpyX; using TomsToolbox.Wpf; @@ -36,7 +37,7 @@ namespace ICSharpCode.ILSpy { private readonly LanguageSettings languageSettings; - public LanguageService(IEnumerable languages, SettingsService settingsService) + public LanguageService(IEnumerable languages, SettingsService settingsService, DockWorkspace dockWorkspace) { languageSettings = settingsService.SessionSettings.LanguageSettings; @@ -44,7 +45,7 @@ namespace ICSharpCode.ILSpy sortedLanguages.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal)); #if DEBUG - sortedLanguages.AddRange(ILAstLanguage.GetDebugLanguages()); + sortedLanguages.AddRange(ILAstLanguage.GetDebugLanguages(dockWorkspace)); sortedLanguages.AddRange(CSharpLanguage.GetDebugLanguages()); #endif AllLanguages = sortedLanguages.AsReadOnly(); diff --git a/ILSpy/MainWindowViewModel.cs b/ILSpy/MainWindowViewModel.cs index b5f22165d..40948ba58 100644 --- a/ILSpy/MainWindowViewModel.cs +++ b/ILSpy/MainWindowViewModel.cs @@ -29,11 +29,14 @@ namespace ICSharpCode.ILSpy { [Export] [Shared] - public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel, SettingsService settingsService, LanguageService languageService) : ObservableObject + public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel, SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace) : ObservableObject { - public DockWorkspace Workspace => DockWorkspace.Instance; + public DockWorkspace Workspace { get; } = dockWorkspace; + public SessionSettings SessionSettings => settingsService.SessionSettings; + public LanguageService LanguageService => languageService; + public AssemblyListManager AssemblyListManager => settingsService.AssemblyListManager; public AnalyzeCommand AnalyzeCommand { get; } = new(assemblyTreeModel, analyzerTreeViewModel); diff --git a/ILSpy/Search/SearchPane.xaml.cs b/ILSpy/Search/SearchPane.xaml.cs index 9cd20e370..94a288f91 100644 --- a/ILSpy/Search/SearchPane.xaml.cs +++ b/ILSpy/Search/SearchPane.xaml.cs @@ -554,9 +554,12 @@ namespace ICSharpCode.ILSpy.Search [Shared] sealed class ShowSearchCommand : CommandWrapper { - public ShowSearchCommand() + private readonly DockWorkspace dockWorkspace; + + public ShowSearchCommand(DockWorkspace dockWorkspace) : base(NavigationCommands.Search) { + this.dockWorkspace = dockWorkspace; var gestures = NavigationCommands.Search.InputGestures; gestures.Clear(); @@ -566,7 +569,7 @@ namespace ICSharpCode.ILSpy.Search protected override void OnExecute(object sender, ExecutedRoutedEventArgs e) { - DockWorkspace.Instance.ShowToolPane(SearchPaneModel.PaneContentId); + dockWorkspace.ShowToolPane(SearchPaneModel.PaneContentId); } } } \ No newline at end of file diff --git a/ILSpy/SolutionWriter.cs b/ILSpy/SolutionWriter.cs index ff0035330..0fee4c18a 100644 --- a/ILSpy/SolutionWriter.cs +++ b/ILSpy/SolutionWriter.cs @@ -47,15 +47,17 @@ namespace ICSharpCode.ILSpy /// to the . The directory of this file must either /// be empty or not exist. /// + /// /// A reference to the instance. /// The target file path of the solution file. + /// /// The assembly nodes to decompile. - /// /// Thrown when is null, /// an empty or a whitespace string. /// Thrown when > or /// is null. - public static void CreateSolution(DecompilerTextView textView, string solutionFilePath, Language language, IEnumerable assemblies) + public static void CreateSolution(TabPageModel tabPage, DecompilerTextView textView, string solutionFilePath, + Language language, IEnumerable assemblies) { if (textView == null) { @@ -75,7 +77,7 @@ namespace ICSharpCode.ILSpy var writer = new SolutionWriter(solutionFilePath); textView - .RunWithCancellation(ct => writer.CreateSolution(assemblies, language, ct)) + .RunWithCancellation(ct => writer.CreateSolution(tabPage, assemblies, language, ct)) .Then(output => textView.ShowText(output)) .HandleExceptions(); } @@ -93,7 +95,7 @@ namespace ICSharpCode.ILSpy projects = new ConcurrentBag(); } - async Task CreateSolution(IEnumerable assemblies, Language language, CancellationToken ct) + async Task CreateSolution(TabPageModel tabPage, IEnumerable assemblies, Language language, CancellationToken ct) { var result = new AvalonEditTextOutput(); @@ -113,7 +115,7 @@ namespace ICSharpCode.ILSpy // long to decompile. await Task.Run(() => Parallel.ForEach(Partitioner.Create(assemblies), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct }, - n => WriteProject(n, language, solutionDirectory, ct))) + item => WriteProject(tabPage, item, language, solutionDirectory, ct))) .ConfigureAwait(false); if (projects.Count == 0) @@ -175,7 +177,7 @@ namespace ICSharpCode.ILSpy return result; } - void WriteProject(LoadedAssembly loadedAssembly, Language language, string targetDirectory, CancellationToken ct) + void WriteProject(TabPageModel tabPage, LoadedAssembly loadedAssembly, Language language, string targetDirectory, CancellationToken ct) { targetDirectory = Path.Combine(targetDirectory, loadedAssembly.ShortName); @@ -214,7 +216,7 @@ namespace ICSharpCode.ILSpy using (var projectFileWriter = new StreamWriter(projectFileName)) { var projectFileOutput = new PlainTextOutput(projectFileWriter); - var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions(); + var options = tabPage.CreateDecompilationOptions(); options.FullDecompilation = true; options.CancellationToken = ct; options.SaveAsProjectDirectory = targetDirectory; diff --git a/ILSpy/TaskHelper.cs b/ILSpy/TaskHelper.cs index 58b2ed1f6..bda3822c9 100644 --- a/ILSpy/TaskHelper.cs +++ b/ILSpy/TaskHelper.cs @@ -20,6 +20,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.TextView; namespace ICSharpCode.ILSpy @@ -200,7 +201,7 @@ namespace ICSharpCode.ILSpy task.Catch(exception => App.Current.Dispatcher.BeginInvoke(new Action(delegate { AvalonEditTextOutput output = new(); output.Write(exception.ToString()); - Docking.DockWorkspace.Instance.ShowText(output); + App.ExportProvider.GetExportedValue().ShowText(output); }))).IgnoreExceptions(); } } diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs index 7812767c8..23b902bb5 100644 --- a/ILSpy/TreeNodes/AssemblyTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs @@ -547,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes dlg.Filter = language.Name + " project|*" + language.ProjectFileExtension + "|" + language.Name + " single file|*" + language.FileExtension + "|All files|*.*"; if (dlg.ShowDialog() == true) { - var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions(); + var options = DockWorkspace.ActiveTabPage.CreateDecompilationOptions(); options.FullDecompilation = true; if (dlg.FilterIndex == 1) { diff --git a/ILSpy/TreeNodes/ILSpyTreeNode.cs b/ILSpy/TreeNodes/ILSpyTreeNode.cs index dbaa2d6ed..ab03c3bb1 100644 --- a/ILSpy/TreeNodes/ILSpyTreeNode.cs +++ b/ILSpy/TreeNodes/ILSpyTreeNode.cs @@ -27,6 +27,7 @@ using System.Windows.Threading; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.AssemblyTree; +using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpyX.Abstractions; using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions; using ICSharpCode.ILSpyX.TreeView; @@ -57,6 +58,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public static LanguageService LanguageService { get; } = App.ExportProvider.GetExportedValue(); + public static DockWorkspace DockWorkspace { get; } = App.ExportProvider.GetExportedValue(); + public virtual FilterResult Filter(LanguageSettings settings) { if (string.IsNullOrEmpty(settings.SearchTerm)) diff --git a/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs b/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs index 69502149f..6cd28d8aa 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs @@ -74,7 +74,7 @@ namespace ICSharpCode.ILSpy.TreeNodes ISmartTextOutput smartOutput = output as ISmartTextOutput; if (smartOutput != null) { - smartOutput.AddButton(Images.Save, Resources.Save, delegate { Save(Docking.DockWorkspace.Instance.ActiveTabPage); }); + smartOutput.AddButton(Images.Save, Resources.Save, delegate { Save(DockWorkspace.ActiveTabPage); }); output.WriteLine(); } } diff --git a/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs b/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs index dec51e183..365b134db 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs @@ -176,7 +176,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { EnsureLazyChildren(); base.Decompile(language, output, options); - var textView = (DecompilerTextView)Docking.DockWorkspace.Instance.ActiveTabPage.Content; + var textView = (DecompilerTextView)DockWorkspace.ActiveTabPage.Content; if (stringTableEntries.Count != 0) { ISmartTextOutput smartOutput = output as ISmartTextOutput; diff --git a/ILSpy/Util/MenuService.cs b/ILSpy/Util/MenuService.cs index 340dd7fb9..3199baf62 100644 --- a/ILSpy/Util/MenuService.cs +++ b/ILSpy/Util/MenuService.cs @@ -38,10 +38,8 @@ namespace ICSharpCode.ILSpy.Util { [Export] [Shared] - public class MenuService(IExportProvider exportProvider) + public class MenuService(IExportProvider exportProvider, DockWorkspace dockWorkspace) { - private readonly DockWorkspace dockWorkspace = DockWorkspace.Instance; - public void Init(Menu mainMenu, ToolBar toolBar, InputBindingCollection inputBindings) { InitMainMenu(mainMenu); @@ -144,7 +142,7 @@ namespace ICSharpCode.ILSpy.Util windowMenuItem.Items.Clear(); var toolItems = dockWorkspace.ToolPanes.Select(toolPane => CreateMenuItem(toolPane, inputBindings)).ToArray(); - var tabItems = dockWorkspace.TabPages.ObservableSelect(tabPage => CreateMenuItem(tabPage, dockWorkspace)); + var tabItems = dockWorkspace.TabPages.ObservableSelect(tabPage => CreateMenuItem(tabPage)); var allItems = new ObservableCompositeCollection(defaultItems, [new Separator()], toolItems, [new Separator()], tabItems); @@ -188,7 +186,7 @@ namespace ICSharpCode.ILSpy.Util } - static Control CreateMenuItem(TabPageModel pane, DockWorkspace dock) + Control CreateMenuItem(TabPageModel pane) { var header = new TextBlock { MaxWidth = 200, @@ -200,13 +198,13 @@ namespace ICSharpCode.ILSpy.Util }); MenuItem menuItem = new() { - Command = new TabPageCommand(pane), + Command = new TabPageCommand(pane, dockWorkspace), Header = header, IsCheckable = true }; - menuItem.SetBinding(MenuItem.IsCheckedProperty, new Binding(nameof(dock.ActiveTabPage)) { - Source = dock, + menuItem.SetBinding(MenuItem.IsCheckedProperty, new Binding(nameof(dockWorkspace.ActiveTabPage)) { + Source = dockWorkspace, ConverterParameter = pane, Converter = BinaryOperationConverter.Equality, Mode = BindingMode.OneWay @@ -215,10 +213,10 @@ namespace ICSharpCode.ILSpy.Util return menuItem; } - static Control CreateMenuItem(ToolPaneModel pane, InputBindingCollection inputBindings) + Control CreateMenuItem(ToolPaneModel pane, InputBindingCollection inputBindings) { MenuItem menuItem = new() { - Command = pane.AssociatedCommand ?? new ToolPaneCommand(pane.ContentId), + Command = pane.AssociatedCommand ?? new ToolPaneCommand(pane.ContentId, dockWorkspace), Header = pane.Title }; var shortcutKey = pane.ShortcutKey; diff --git a/ILSpy/ViewModels/PaneModel.cs b/ILSpy/ViewModels/PaneModel.cs index f9ef1b90e..95d598d63 100644 --- a/ILSpy/ViewModels/PaneModel.cs +++ b/ILSpy/ViewModels/PaneModel.cs @@ -22,6 +22,7 @@ using System.Windows; using System.Windows.Input; using ICSharpCode.Decompiler.IL; +using ICSharpCode.ILSpy.Docking; using TomsToolbox.Wpf; @@ -31,6 +32,8 @@ namespace ICSharpCode.ILSpy.ViewModels { private Throttle titleChangeThrottle; + public static DockWorkspace DockWorkspace => App.ExportProvider.GetExportedValue(); + protected PaneModel() { titleChangeThrottle = new Throttle(() => OnPropertyChanged(nameof(Title))); @@ -63,7 +66,7 @@ namespace ICSharpCode.ILSpy.ViewModels public void Execute(object parameter) { - Docking.DockWorkspace.Instance.Remove(model); + DockWorkspace.Remove(model); } } diff --git a/ILSpy/Views/DebugSteps.xaml.cs b/ILSpy/Views/DebugSteps.xaml.cs index 9442eff70..c341c37ab 100644 --- a/ILSpy/Views/DebugSteps.xaml.cs +++ b/ILSpy/Views/DebugSteps.xaml.cs @@ -22,6 +22,7 @@ namespace ICSharpCode.ILSpy private readonly AssemblyTreeModel assemblyTreeModel; private readonly SettingsService settingsService; private readonly LanguageService languageService; + private readonly DockWorkspace dockWorkspace; static readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions { UseFieldSugar = true, @@ -33,12 +34,13 @@ namespace ICSharpCode.ILSpy #if DEBUG ILAstLanguage language; #endif - public DebugSteps(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService) + public DebugSteps(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace) { this.assemblyTreeModel = assemblyTreeModel; this.settingsService = settingsService; this.languageService = languageService; - + this.dockWorkspace = dockWorkspace; + InitializeComponent(); #if DEBUG @@ -132,8 +134,8 @@ namespace ICSharpCode.ILSpy void DecompileAsync(int step, bool isDebug = false) { lastSelectedStep = step; - var state = DockWorkspace.Instance.ActiveTabPage.GetState(); - DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes, + var state = dockWorkspace.ActiveTabPage.GetState(); + dockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes, new DecompilationOptions(assemblyTreeModel.CurrentLanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) { StepLimit = step, IsDebug = isDebug,