Browse Source

Merge pull request #2554 from icsharpcode/fix-ui-typesystem

Fix typesystems used in the UI
pull/2560/head
Siegfried Pammer 4 years ago committed by GitHub
parent
commit
70c17dd1c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      ILSpy/Analyzers/AnalyzerTreeView.cs
  2. 58
      ILSpy/Docking/DockWorkspace.cs
  3. 31
      ILSpy/FilterSettings.cs
  4. 22
      ILSpy/MainWindow.xaml
  5. 67
      ILSpy/MainWindow.xaml.cs
  6. 30
      ILSpy/MainWindowViewModel.cs
  7. 17
      ILSpy/Search/SearchPane.cs
  8. 2
      ILSpy/SessionSettings.cs
  9. 7
      ILSpy/TextView/DecompilerTextView.cs
  10. 2
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  11. 14
      ILSpy/TreeNodes/EventTreeNode.cs
  12. 14
      ILSpy/TreeNodes/FieldTreeNode.cs
  13. 14
      ILSpy/TreeNodes/MethodTreeNode.cs
  14. 17
      ILSpy/TreeNodes/PropertyTreeNode.cs
  15. 14
      ILSpy/TreeNodes/TypeTreeNode.cs
  16. 10
      ILSpy/ViewModels/ManageAssemblyListsViewModel.cs
  17. 59
      ILSpy/ViewModels/TabPageModel.cs
  18. 18
      ILSpy/Views/DebugSteps.xaml.cs

18
ILSpy/Analyzers/AnalyzerTreeView.cs

@ -35,6 +35,8 @@ namespace ICSharpCode.ILSpy.Analyzers
/// </summary> /// </summary>
public class AnalyzerTreeView : SharpTreeView public class AnalyzerTreeView : SharpTreeView
{ {
FilterSettings filterSettings;
public AnalyzerTreeView() public AnalyzerTreeView()
{ {
this.ShowRoot = false; this.ShowRoot = false;
@ -42,7 +44,21 @@ namespace ICSharpCode.ILSpy.Analyzers
this.BorderThickness = new Thickness(0); this.BorderThickness = new Thickness(0);
ContextMenuProvider.Add(this); ContextMenuProvider.Add(this);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged; MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged; DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
filterSettings = MainWindow.Instance.SessionSettings.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
}
private void DockWorkspace_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
break;
}
} }
private void FilterSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void FilterSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

58
ILSpy/Docking/DockWorkspace.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.Linq; using System.Linq;
@ -45,14 +46,46 @@ namespace ICSharpCode.ILSpy.Docking
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
public static DockWorkspace Instance { get; } = new DockWorkspace(); public static DockWorkspace Instance { get; private set; }
private DockWorkspace() internal DockWorkspace(MainWindow parent)
{ {
Instance = this;
this.TabPages.CollectionChanged += Documents_CollectionChanged; this.TabPages.CollectionChanged += Documents_CollectionChanged;
parent.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
} }
private void Documents_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) private void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems == null)
{
return;
}
foreach (var tab in TabPages.ToArray())
{
var state = tab.GetState();
if (state == null || state.DecompiledNodes == null)
{
continue;
}
bool found = false;
foreach (var node in state.DecompiledNodes)
{
var assemblyNode = node.Ancestors().OfType<TreeNodes.AssemblyTreeNode>().LastOrDefault();
if (assemblyNode != null && !e.OldItems.Contains(assemblyNode.LoadedAssembly))
{
found = true;
break;
}
}
if (!found && TabPages.Count > 1)
{
TabPages.Remove(tab);
}
}
}
private void Documents_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{ {
var collection = (PaneCollection<TabPageModel>)sender; var collection = (PaneCollection<TabPageModel>)sender;
bool canClose = collection.Count > 1; bool canClose = collection.Count > 1;
@ -94,8 +127,6 @@ namespace ICSharpCode.ILSpy.Docking
if (_activeTabPage != value) if (_activeTabPage != value)
{ {
_activeTabPage = value; _activeTabPage = value;
this.sessionSettings.FilterSettings.Language = value.Language;
this.sessionSettings.FilterSettings.LanguageVersion = value.LanguageVersion;
var state = value.GetState(); var state = value.GetState();
if (state != null) if (state != null)
{ {
@ -173,23 +204,6 @@ namespace ICSharpCode.ILSpy.Docking
internal void LoadSettings(SessionSettings sessionSettings) internal void LoadSettings(SessionSettings sessionSettings)
{ {
this.sessionSettings = sessionSettings; this.sessionSettings = sessionSettings;
sessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged;
}
private void FilterSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Language")
{
ActiveTabPage.Language = sessionSettings.FilterSettings.Language;
if (sessionSettings.FilterSettings.Language.HasLanguageVersions)
{
sessionSettings.FilterSettings.LanguageVersion = ActiveTabPage.LanguageVersion;
}
}
else if (e.PropertyName == "LanguageVersion")
{
ActiveTabPage.LanguageVersion = sessionSettings.FilterSettings.LanguageVersion;
}
} }
internal void CloseAllTabs() internal void CloseAllTabs()

31
ILSpy/FilterSettings.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -34,6 +35,13 @@ namespace ICSharpCode.ILSpy
/// </remarks> /// </remarks>
public class FilterSettings : INotifyPropertyChanged public class FilterSettings : INotifyPropertyChanged
{ {
/// <summary>
/// This dictionary is necessary to remember language versions across language changes. For example,
/// the user first select C# 10, then switches to IL, then switches back to C#. After that we must be
/// able to restore the original selection (i.e., C# 10).
/// </summary>
private readonly Dictionary<Language, LanguageVersion> languageVersionHistory = new Dictionary<Language, LanguageVersion>();
public FilterSettings(XElement element) public FilterSettings(XElement element)
{ {
this.ShowApiLevel = (ApiVisibility?)(int?)element.Element("ShowAPILevel") ?? ApiVisibility.PublicAndInternal; this.ShowApiLevel = (ApiVisibility?)(int?)element.Element("ShowAPILevel") ?? ApiVisibility.PublicAndInternal;
@ -146,8 +154,27 @@ namespace ICSharpCode.ILSpy
set { set {
if (language != value) if (language != value)
{ {
if (language != null && language.HasLanguageVersions)
{
languageVersionHistory[language] = languageVersion;
}
language = value; language = value;
OnPropertyChanged(); OnPropertyChanged();
if (language.HasLanguageVersions)
{
if (languageVersionHistory.TryGetValue(value, out var version))
{
LanguageVersion = version;
}
else
{
LanguageVersion = Language.LanguageVersions.Last();
}
}
else
{
LanguageVersion = default;
}
} }
} }
} }
@ -167,6 +194,10 @@ namespace ICSharpCode.ILSpy
if (languageVersion != value) if (languageVersion != value)
{ {
languageVersion = value; languageVersion = value;
if (language.HasLanguageVersions)
{
languageVersionHistory[language] = languageVersion;
}
OnPropertyChanged(); OnPropertyChanged();
} }
} }

22
ILSpy/MainWindow.xaml

@ -19,7 +19,7 @@
xmlns:styles="urn:TomsToolbox.Wpf.Styles" xmlns:styles="urn:TomsToolbox.Wpf.Styles"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors" xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes"
d:DataContext="{d:DesignInstance local:MainWindowDataContext}" d:DataContext="{d:DesignInstance local:MainWindowViewModel}"
> >
<Window.Resources> <Window.Resources>
<controls:BoolToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> <controls:BoolToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
@ -103,9 +103,9 @@
<MenuItem Header="{x:Static properties:Resources._File}" /> <MenuItem Header="{x:Static properties:Resources._File}" />
<!-- contents of file menu are added using MEF --> <!-- contents of file menu are added using MEF -->
<MenuItem Header="{x:Static properties:Resources._View}"> <MenuItem Header="{x:Static properties:Resources._View}">
<MenuItem Header="{x:Static properties:Resources.Show_publiconlyTypesMembers}" IsCheckable="True" IsChecked="{Binding SessionSettings.FilterSettings.ApiVisPublicOnly}" /> <MenuItem Header="{x:Static properties:Resources.Show_publiconlyTypesMembers}" IsCheckable="True" IsChecked="{Binding Workspace.ActiveTabPage.FilterSettings.ApiVisPublicOnly}" />
<MenuItem Header="{x:Static properties:Resources.Show_internalTypesMembers}" IsCheckable="True" IsChecked="{Binding SessionSettings.FilterSettings.ApiVisPublicAndInternal}" /> <MenuItem Header="{x:Static properties:Resources.Show_internalTypesMembers}" IsCheckable="True" IsChecked="{Binding Workspace.ActiveTabPage.FilterSettings.ApiVisPublicAndInternal}" />
<MenuItem Header="{x:Static properties:Resources.Show_allTypesAndMembers}" IsCheckable="True" IsChecked="{Binding SessionSettings.FilterSettings.ApiVisAll}" /> <MenuItem Header="{x:Static properties:Resources.Show_allTypesAndMembers}" IsCheckable="True" IsChecked="{Binding Workspace.ActiveTabPage.FilterSettings.ApiVisAll}" />
<Separator/> <Separator/>
<MenuItem Header="{x:Static properties:Resources.UILanguage}"> <MenuItem Header="{x:Static properties:Resources.UILanguage}">
<MenuItem Header="{x:Static properties:Resources.UILanguage_System}" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={StaticResource cultureSelectionConverter}, ConverterParameter={x:Null}}" /> <MenuItem Header="{x:Static properties:Resources.UILanguage_System}" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={StaticResource cultureSelectionConverter}, ConverterParameter={x:Null}}" />
@ -156,25 +156,25 @@
<Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}" Style="{StaticResource DarkModeAwareImageStyle}"/> <Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</Button> </Button>
<Separator /> <Separator />
<CheckBox IsChecked="{Binding SessionSettings.FilterSettings.ApiVisPublicOnly}" ToolTip="{x:Static properties:Resources.ShowPublicOnlyTypesMembers}"> <CheckBox IsChecked="{Binding Workspace.ActiveTabPage.FilterSettings.ApiVisPublicOnly}" ToolTip="{x:Static properties:Resources.ShowPublicOnlyTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPublicOnly}" Style="{StaticResource DarkModeAwareImageStyle}"/> <Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPublicOnly}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding SessionSettings.FilterSettings.ApiVisPublicAndInternal}" ToolTip="{x:Static properties:Resources.ShowInternalTypesMembers}"> <CheckBox IsChecked="{Binding Workspace.ActiveTabPage.FilterSettings.ApiVisPublicAndInternal}" ToolTip="{x:Static properties:Resources.ShowInternalTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPrivateInternal}" Style="{StaticResource DarkModeAwareImageStyle}"/> <Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPrivateInternal}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding SessionSettings.FilterSettings.ApiVisAll}" ToolTip="{x:Static properties:Resources.ShowAllTypesAndMembers}"> <CheckBox IsChecked="{Binding Workspace.ActiveTabPage.FilterSettings.ApiVisAll}" ToolTip="{x:Static properties:Resources.ShowAllTypesAndMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowAll}" Style="{StaticResource DarkModeAwareImageStyle}"/> <Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowAll}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox> </CheckBox>
<Separator /> <Separator />
<ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100" MaxDropDownHeight="Auto" <ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100" MaxDropDownHeight="Auto"
IsEnabled="{Binding ActiveTabPage.SupportsLanguageSwitching, Source={x:Static docking:DockWorkspace.Instance}}" IsEnabled="{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}"
ItemsSource="{x:Static local:Languages.AllLanguages}" ToolTip="{x:Static properties:Resources.SelectLanguageDropdownTooltip}" ItemsSource="{x:Static local:Languages.AllLanguages}" ToolTip="{x:Static properties:Resources.SelectLanguageDropdownTooltip}"
SelectedItem="{Binding SessionSettings.FilterSettings.Language}"/> SelectedItem="{Binding Workspace.ActiveTabPage.FilterSettings.Language}"/>
<ComboBox Name="languageVersionComboBox" DisplayMemberPath="DisplayName" Width="120" MaxDropDownHeight="Auto" ToolTip="{x:Static properties:Resources.SelectVersionDropdownTooltip}" <ComboBox Name="languageVersionComboBox" DisplayMemberPath="DisplayName" Width="120" MaxDropDownHeight="Auto" ToolTip="{x:Static properties:Resources.SelectVersionDropdownTooltip}"
Visibility="{Binding SelectedItem.HasLanguageVersions, ElementName=languageComboBox, Converter={StaticResource BooleanToVisibilityConverter}}" Visibility="{Binding SelectedItem.HasLanguageVersions, ElementName=languageComboBox, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEnabled="{Binding ActiveTabPage.SupportsLanguageSwitching, Source={x:Static docking:DockWorkspace.Instance}}" IsEnabled="{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}"
ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SessionSettings.FilterSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/> SelectedItem="{Binding Workspace.ActiveTabPage.FilterSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/>
<Separator /> <Separator />
<CheckBox IsChecked="{Binding SessionSettings.IsDarkMode}" ToolTip="{x:Static properties:Resources.DarkMode}"> <CheckBox IsChecked="{Binding SessionSettings.IsDarkMode}" ToolTip="{x:Static properties:Resources.DarkMode}">
<Image Source="Images/DarkMode.png" Stretch="None" Style="{StaticResource DarkModeAwareImageStyle}"/> <Image Source="Images/DarkMode.png" Stretch="None" Style="{StaticResource DarkModeAwareImageStyle}"/>

67
ILSpy/MainWindow.xaml.cs

@ -32,7 +32,6 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Threading; using System.Windows.Threading;
@ -55,13 +54,6 @@ using Microsoft.Win32;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
{ {
class MainWindowDataContext
{
public DockWorkspace Workspace { get; set; }
public SessionSettings SessionSettings { get; set; }
public AssemblyListManager AssemblyListManager { get; set; }
}
/// <summary> /// <summary>
/// The main window of the application. /// The main window of the application.
/// </summary> /// </summary>
@ -70,7 +62,8 @@ namespace ICSharpCode.ILSpy
bool refreshInProgress, changingActiveTab; bool refreshInProgress, changingActiveTab;
readonly NavigationHistory<NavigationState> history = new NavigationHistory<NavigationState>(); readonly NavigationHistory<NavigationState> history = new NavigationHistory<NavigationState>();
ILSpySettings spySettingsForMainWindow_Loaded; ILSpySettings spySettingsForMainWindow_Loaded;
internal SessionSettings sessionSettings; SessionSettings sessionSettings;
FilterSettings filterSettings;
AssemblyList assemblyList; AssemblyList assemblyList;
AssemblyListTreeNode assemblyListTreeNode; AssemblyListTreeNode assemblyListTreeNode;
@ -115,8 +108,8 @@ namespace ICSharpCode.ILSpy
// Make sure Images are initialized on the UI thread. // Make sure Images are initialized on the UI thread.
this.Icon = Images.ILSpyIcon; this.Icon = Images.ILSpyIcon;
this.DataContext = new MainWindowDataContext { this.DataContext = new MainWindowViewModel {
Workspace = DockWorkspace.Instance, Workspace = new DockWorkspace(this),
SessionSettings = sessionSettings, SessionSettings = sessionSettings,
AssemblyListManager = AssemblyListManager AssemblyListManager = AssemblyListManager
}; };
@ -130,8 +123,10 @@ namespace ICSharpCode.ILSpy
InitializeComponent(); InitializeComponent();
InitToolPanes(); InitToolPanes();
DockWorkspace.Instance.InitializeLayout(DockManager); DockWorkspace.Instance.InitializeLayout(DockManager);
sessionSettings.FilterSettings.PropertyChanged += filterSettings_PropertyChanged;
sessionSettings.PropertyChanged += SessionSettings_PropertyChanged; sessionSettings.PropertyChanged += SessionSettings_PropertyChanged;
filterSettings = sessionSettings.FilterSettings;
filterSettings.PropertyChanged += filterSettings_PropertyChanged;
DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
InitMainMenu(); InitMainMenu();
InitToolbar(); InitToolbar();
ContextMenuProvider.Add(AssemblyTreeView); ContextMenuProvider.Add(AssemblyTreeView);
@ -139,6 +134,18 @@ namespace ICSharpCode.ILSpy
this.Loaded += MainWindow_Loaded; this.Loaded += MainWindow_Loaded;
} }
private void DockWorkspace_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
filterSettings.PropertyChanged -= filterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += filterSettings_PropertyChanged;
break;
}
}
private void SessionSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) private void SessionSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
switch (e.PropertyName) switch (e.PropertyName)
@ -406,7 +413,7 @@ namespace ICSharpCode.ILSpy
{ {
LoadAssemblies(args.AssembliesToLoad, commandLineLoadedAssemblies, focusNode: false); LoadAssemblies(args.AssembliesToLoad, commandLineLoadedAssemblies, focusNode: false);
if (args.Language != null) if (args.Language != null)
sessionSettings.FilterSettings.Language = Languages.GetLanguage(args.Language); filterSettings.Language = Languages.GetLanguage(args.Language);
return true; return true;
} }
@ -597,8 +604,7 @@ namespace ICSharpCode.ILSpy
void MainWindow_Loaded(object sender, RoutedEventArgs e) void MainWindow_Loaded(object sender, RoutedEventArgs e)
{ {
DockWorkspace.Instance.TabPages.Add(new TabPageModel() { DockWorkspace.Instance.TabPages.Add(new TabPageModel() {
Language = CurrentLanguage, FilterSettings = filterSettings.Clone()
LanguageVersion = CurrentLanguageVersion
}); });
DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.First(); DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.First();
@ -770,7 +776,7 @@ namespace ICSharpCode.ILSpy
assemblyList.CollectionChanged += assemblyList_Assemblies_CollectionChanged; assemblyList.CollectionChanged += assemblyList_Assemblies_CollectionChanged;
assemblyListTreeNode = new AssemblyListTreeNode(assemblyList); assemblyListTreeNode = new AssemblyListTreeNode(assemblyList);
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone(); assemblyListTreeNode.FilterSettings = filterSettings.Clone();
assemblyListTreeNode.Select = x => SelectNode(x, inNewTabPage: false); assemblyListTreeNode.Select = x => SelectNode(x, inNewTabPage: false);
AssemblyTreeView.Root = assemblyListTreeNode; AssemblyTreeView.Root = assemblyListTreeNode;
@ -824,7 +830,6 @@ namespace ICSharpCode.ILSpy
void filterSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) void filterSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
RefreshTreeView();
RefreshTreeViewFilter(); RefreshTreeViewFilter();
if (e.PropertyName == "Language" || e.PropertyName == "LanguageVersion") if (e.PropertyName == "Language" || e.PropertyName == "LanguageVersion")
{ {
@ -838,7 +843,7 @@ namespace ICSharpCode.ILSpy
// Thus, the main window will use one mutable instance (for data-binding), and assign a new clone to the ILSpyTreeNodes whenever the main // Thus, the main window will use one mutable instance (for data-binding), and assign a new clone to the ILSpyTreeNodes whenever the main
// mutable instance changes. // mutable instance changes.
if (assemblyListTreeNode != null) if (assemblyListTreeNode != null)
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone(); assemblyListTreeNode.FilterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings.Clone();
} }
internal AssemblyListTreeNode AssemblyListTreeNode { internal AssemblyListTreeNode AssemblyListTreeNode {
@ -867,8 +872,7 @@ namespace ICSharpCode.ILSpy
{ {
DockWorkspace.Instance.TabPages.Add( DockWorkspace.Instance.TabPages.Add(
new TabPageModel() { new TabPageModel() {
Language = CurrentLanguage, FilterSettings = filterSettings.Clone()
LanguageVersion = CurrentLanguageVersion
}); });
DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.Last(); DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.Last();
AssemblyTreeView.SelectedItem = null; AssemblyTreeView.SelectedItem = null;
@ -914,8 +918,7 @@ namespace ICSharpCode.ILSpy
{ {
DockWorkspace.Instance.TabPages.Add( DockWorkspace.Instance.TabPages.Add(
new TabPageModel() { new TabPageModel() {
Language = CurrentLanguage, FilterSettings = filterSettings.Clone()
LanguageVersion = CurrentLanguageVersion
}); });
DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.Last(); DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.Last();
} }
@ -1173,11 +1176,6 @@ namespace ICSharpCode.ILSpy
} }
void RefreshCommandExecuted(object sender, ExecutedRoutedEventArgs e) void RefreshCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
RefreshTreeView();
}
void RefreshTreeView()
{ {
try try
{ {
@ -1206,7 +1204,10 @@ namespace ICSharpCode.ILSpy
{ {
state = DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState; state = DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState;
} }
DecompileSelectedNodes(state); if (!changingActiveTab)
{
DecompileSelectedNodes(state);
}
SelectionChanged?.Invoke(sender, e); SelectionChanged?.Invoke(sender, e);
} }
@ -1274,8 +1275,10 @@ namespace ICSharpCode.ILSpy
} }
} }
public Language CurrentLanguage => sessionSettings.FilterSettings.Language; public Language CurrentLanguage => DockWorkspace.Instance.ActiveTabPage.FilterSettings.Language;
public LanguageVersion CurrentLanguageVersion => sessionSettings.FilterSettings.LanguageVersion; public LanguageVersion CurrentLanguageVersion => DockWorkspace.Instance.ActiveTabPage.FilterSettings.LanguageVersion;
public bool SupportsLanguageSwitching => DockWorkspace.Instance.ActiveTabPage.SupportsLanguageSwitching;
public event SelectionChangedEventHandler SelectionChanged; public event SelectionChangedEventHandler SelectionChanged;
@ -1347,8 +1350,7 @@ namespace ICSharpCode.ILSpy
{ {
DockWorkspace.Instance.TabPages.Add( DockWorkspace.Instance.TabPages.Add(
new TabPageModel() { new TabPageModel() {
Language = CurrentLanguage, FilterSettings = filterSettings.Clone()
LanguageVersion = CurrentLanguageVersion
}); });
DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.Last(); DockWorkspace.Instance.ActiveTabPage = DockWorkspace.Instance.TabPages.Last();
} }
@ -1413,6 +1415,7 @@ namespace ICSharpCode.ILSpy
sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(AssemblyTreeView.SelectedItem as SharpTreeNode); sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(AssemblyTreeView.SelectedItem as SharpTreeNode);
sessionSettings.WindowBounds = this.RestoreBounds; sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(DockManager)); sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(DockManager));
sessionSettings.FilterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings.Clone();
sessionSettings.Save(); sessionSettings.Save();
} }

30
ILSpy/MainWindowViewModel.cs

@ -0,0 +1,30 @@
// Copyright (c) 2021 Siegfried Pammer
//
// 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 ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy
{
class MainWindowViewModel
{
public DockWorkspace Workspace { get; set; }
public SessionSettings SessionSettings { get; set; }
public AssemblyListManager AssemblyListManager { get; set; }
}
}

17
ILSpy/Search/SearchPane.cs

@ -50,6 +50,7 @@ namespace ICSharpCode.ILSpy
RunningSearch currentSearch; RunningSearch currentSearch;
bool runSearchOnNextShow; bool runSearchOnNextShow;
IComparer<SearchResult> resultsComparer; IComparer<SearchResult> resultsComparer;
FilterSettings filterSettings;
public static readonly DependencyProperty ResultsProperty = public static readonly DependencyProperty ResultsProperty =
DependencyProperty.Register("Results", typeof(ObservableCollection<SearchResult>), typeof(SearchPane), DependencyProperty.Register("Results", typeof(ObservableCollection<SearchResult>), typeof(SearchPane),
@ -76,13 +77,27 @@ namespace ICSharpCode.ILSpy
ContextMenuProvider.Add(listBox); ContextMenuProvider.Add(listBox);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged; MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged; DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
filterSettings = MainWindow.Instance.SessionSettings.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
CompositionTarget.Rendering += UpdateResults; CompositionTarget.Rendering += UpdateResults;
// This starts empty search right away, so do at the end (we're still in ctor) // This starts empty search right away, so do at the end (we're still in ctor)
searchModeComboBox.SelectedIndex = (int)MainWindow.Instance.SessionSettings.SelectedSearchMode; searchModeComboBox.SelectedIndex = (int)MainWindow.Instance.SessionSettings.SelectedSearchMode;
} }
private void DockWorkspace_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
break;
}
}
void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e) void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e)
{ {
if (IsVisible) if (IsVisible)

2
ILSpy/SessionSettings.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.ILSpy
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
public FilterSettings FilterSettings { get; private set; } public FilterSettings FilterSettings { get; internal set; }
public SearchMode SelectedSearchMode { get; set; } public SearchMode SelectedSearchMode { get; set; }
public bool IsDarkMode { public bool IsDarkMode {

7
ILSpy/TextView/DecompilerTextView.cs

@ -152,7 +152,7 @@ namespace ICSharpCode.ILSpy.TextView
{ {
if (this.DataContext is PaneModel model) if (this.DataContext is PaneModel model)
{ {
model.Title = currentTitle ?? ILSpy.Properties.Resources.NewTab; model.Title = currentTitle ?? ILSpy.Properties.Resources.Decompiling;
} }
} }
@ -665,8 +665,8 @@ namespace ICSharpCode.ILSpy.TextView
textOutput.Title = string.Join(", ", nodes.Select(n => n.Text)); textOutput.Title = string.Join(", ", nodes.Select(n => n.Text));
} }
ShowOutput(textOutput, highlighting);
decompiledNodes = nodes; decompiledNodes = nodes;
ShowOutput(textOutput, highlighting);
} }
/// <summary> /// <summary>
@ -815,12 +815,12 @@ namespace ICSharpCode.ILSpy.TextView
return RunWithCancellation( return RunWithCancellation(
delegate (CancellationToken ct) { // creation of the background task delegate (CancellationToken ct) { // creation of the background task
context.Options.CancellationToken = ct; context.Options.CancellationToken = ct;
decompiledNodes = context.TreeNodes;
return DecompileAsync(context, outputLengthLimit); return DecompileAsync(context, outputLengthLimit);
}) })
.Then( .Then(
delegate (AvalonEditTextOutput textOutput) { // handling the result delegate (AvalonEditTextOutput textOutput) { // handling the result
ShowOutput(textOutput, context.Language.SyntaxHighlighting, context.Options.TextViewState); ShowOutput(textOutput, context.Language.SyntaxHighlighting, context.Options.TextViewState);
decompiledNodes = context.TreeNodes;
}) })
.Catch<Exception>(exception => { .Catch<Exception>(exception => {
textEditor.SyntaxHighlighting = null; textEditor.SyntaxHighlighting = null;
@ -835,7 +835,6 @@ namespace ICSharpCode.ILSpy.TextView
output.WriteLine(exception.ToString()); output.WriteLine(exception.ToString());
} }
ShowOutput(output); ShowOutput(output);
decompiledNodes = context.TreeNodes;
}); });
} }

2
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -200,7 +200,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
void LoadChildrenForPEFile(PEFile module) void LoadChildrenForPEFile(PEFile module)
{ {
typeSystem = LoadedAssembly.GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(new DecompilationOptions().DecompilerSettings)); typeSystem = LoadedAssembly.GetTypeSystemOrNull();
var assembly = (MetadataModule)typeSystem.MainModule; var assembly = (MetadataModule)typeSystem.MainModule;
this.Children.Add(new Metadata.MetadataTreeNode(module, this)); this.Children.Add(new Metadata.MetadataTreeNode(module, this));
Decompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull(); Decompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull();

14
ILSpy/TreeNodes/EventTreeNode.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Reflection.Metadata;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
@ -45,14 +46,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
public IEvent EventDefinition { get; } public IEvent EventDefinition { get; }
public override object Text => GetText(EventDefinition, this.Language) + EventDefinition.MetadataToken.ToSuffixString(); public override object Text => GetText(GetEventDefinition(), this.Language) + EventDefinition.MetadataToken.ToSuffixString();
private IEvent GetEventDefinition()
{
return ((MetadataModule)EventDefinition.ParentModule.PEFile
?.GetTypeSystemWithCurrentOptionsOrNull()
?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition;
}
public static object GetText(IEvent ev, Language language) public static object GetText(IEvent ev, Language language)
{ {
return language.EventToString(ev, false, false, false); return language.EventToString(ev, false, false, false);
} }
public override object Icon => GetIcon(EventDefinition); public override object Icon => GetIcon(GetEventDefinition());
public static ImageSource GetIcon(IEvent @event) public static ImageSource GetIcon(IEvent @event)
{ {
@ -76,7 +84,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (EventDefinition.Accessibility) switch (GetEventDefinition().Accessibility)
{ {
case Accessibility.Public: case Accessibility.Public:
case Accessibility.ProtectedOrInternal: case Accessibility.ProtectedOrInternal:

14
ILSpy/TreeNodes/FieldTreeNode.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Reflection.Metadata;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
@ -37,14 +38,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.FieldDefinition = field ?? throw new ArgumentNullException(nameof(field)); this.FieldDefinition = field ?? throw new ArgumentNullException(nameof(field));
} }
public override object Text => GetText(FieldDefinition, Language) + FieldDefinition.MetadataToken.ToSuffixString(); public override object Text => GetText(GetFieldDefinition(), Language) + FieldDefinition.MetadataToken.ToSuffixString();
private IField GetFieldDefinition()
{
return ((MetadataModule)FieldDefinition.ParentModule.PEFile
?.GetTypeSystemWithCurrentOptionsOrNull()
?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition;
}
public static object GetText(IField field, Language language) public static object GetText(IField field, Language language)
{ {
return language.FieldToString(field, includeDeclaringTypeName: false, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false); return language.FieldToString(field, includeDeclaringTypeName: false, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false);
} }
public override object Icon => GetIcon(FieldDefinition); public override object Icon => GetIcon(GetFieldDefinition());
public static ImageSource GetIcon(IField field) public static ImageSource GetIcon(IField field)
{ {
@ -77,7 +85,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (FieldDefinition.Accessibility) switch (GetFieldDefinition().Accessibility)
{ {
case Accessibility.Public: case Accessibility.Public:
case Accessibility.Protected: case Accessibility.Protected:

14
ILSpy/TreeNodes/MethodTreeNode.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Reflection.Metadata;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
@ -37,14 +38,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.MethodDefinition = method ?? throw new ArgumentNullException(nameof(method)); this.MethodDefinition = method ?? throw new ArgumentNullException(nameof(method));
} }
public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.MetadataToken.ToSuffixString(); public override object Text => GetText(GetMethodDefinition(), Language) + MethodDefinition.MetadataToken.ToSuffixString();
private IMethod GetMethodDefinition()
{
return ((MetadataModule)MethodDefinition.ParentModule.PEFile
?.GetTypeSystemWithCurrentOptionsOrNull()
?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition;
}
public static object GetText(IMethod method, Language language) public static object GetText(IMethod method, Language language)
{ {
return language.MethodToString(method, false, false, false); return language.MethodToString(method, false, false, false);
} }
public override object Icon => GetIcon(MethodDefinition); public override object Icon => GetIcon(GetMethodDefinition());
public static ImageSource GetIcon(IMethod method) public static ImageSource GetIcon(IMethod method)
{ {
@ -102,7 +110,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (MethodDefinition.Accessibility) switch (GetMethodDefinition().Accessibility)
{ {
case Accessibility.Public: case Accessibility.Public:
case Accessibility.Protected: case Accessibility.Protected:

17
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -17,14 +17,10 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes namespace ICSharpCode.ILSpy.TreeNodes
{ {
@ -52,14 +48,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
public IProperty PropertyDefinition { get; } public IProperty PropertyDefinition { get; }
public override object Text => GetText(PropertyDefinition, Language) + PropertyDefinition.MetadataToken.ToSuffixString(); public override object Text => GetText(GetPropertyDefinition(), Language) + PropertyDefinition.MetadataToken.ToSuffixString();
private IProperty GetPropertyDefinition()
{
return ((MetadataModule)PropertyDefinition.ParentModule.PEFile
?.GetTypeSystemWithCurrentOptionsOrNull()
?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition;
}
public static object GetText(IProperty property, Language language) public static object GetText(IProperty property, Language language)
{ {
return language.PropertyToString(property, false, false, false); return language.PropertyToString(property, false, false, false);
} }
public override object Icon => GetIcon(PropertyDefinition); public override object Icon => GetIcon(GetPropertyDefinition());
public static ImageSource GetIcon(IProperty property) public static ImageSource GetIcon(IProperty property)
{ {
@ -84,7 +87,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (PropertyDefinition.Accessibility) switch (GetPropertyDefinition().Accessibility)
{ {
case Accessibility.Public: case Accessibility.Public:
case Accessibility.ProtectedOrInternal: case Accessibility.ProtectedOrInternal:

14
ILSpy/TreeNodes/TypeTreeNode.cs

@ -41,12 +41,20 @@ namespace ICSharpCode.ILSpy.TreeNodes
public AssemblyTreeNode ParentAssemblyNode { get; } public AssemblyTreeNode ParentAssemblyNode { get; }
public override object Text => this.Language.TypeToString(TypeDefinition, includeNamespace: false) public override object Text => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: false)
+ TypeDefinition.MetadataToken.ToSuffixString(); + TypeDefinition.MetadataToken.ToSuffixString();
private ITypeDefinition GetTypeDefinition()
{
return ((MetadataModule)ParentAssemblyNode.LoadedAssembly
.GetPEFileOrNull()
?.GetTypeSystemWithCurrentOptionsOrNull()
?.MainModule).GetDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken);
}
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (TypeDefinition.Accessibility) switch (GetTypeDefinition().Accessibility)
{ {
case Accessibility.Public: case Accessibility.Public:
case Accessibility.Protected: case Accessibility.Protected:
@ -120,7 +128,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{ {
language.DecompileType(TypeDefinition, output, options); language.DecompileType(GetTypeDefinition(), output, options);
} }
public override object Icon => GetIcon(TypeDefinition); public override object Icon => GetIcon(TypeDefinition);

10
ILSpy/ViewModels/ManageAssemblyListsViewModel.cs

@ -191,9 +191,9 @@ namespace ICSharpCode.ILSpy.ViewModels
if (manager.AssemblyLists.Count > 0) if (manager.AssemblyLists.Count > 0)
{ {
SelectedAssemblyList = manager.AssemblyLists[Math.Max(0, index - 1)]; SelectedAssemblyList = manager.AssemblyLists[Math.Max(0, index - 1)];
if (MainWindow.Instance.sessionSettings.ActiveAssemblyList == assemblyList) if (MainWindow.Instance.SessionSettings.ActiveAssemblyList == assemblyList)
{ {
MainWindow.Instance.sessionSettings.ActiveAssemblyList = SelectedAssemblyList; MainWindow.Instance.SessionSettings.ActiveAssemblyList = SelectedAssemblyList;
} }
} }
} }
@ -234,9 +234,9 @@ namespace ICSharpCode.ILSpy.ViewModels
string assemblyList = SelectedAssemblyList; string assemblyList = SelectedAssemblyList;
SelectedAssemblyList = dlg.ListName; SelectedAssemblyList = dlg.ListName;
manager.RenameList(assemblyList, dlg.ListName); manager.RenameList(assemblyList, dlg.ListName);
if (MainWindow.Instance.sessionSettings.ActiveAssemblyList == assemblyList) if (MainWindow.Instance.SessionSettings.ActiveAssemblyList == assemblyList)
{ {
MainWindow.Instance.sessionSettings.ActiveAssemblyList = manager.AssemblyLists[manager.AssemblyLists.Count - 1]; MainWindow.Instance.SessionSettings.ActiveAssemblyList = manager.AssemblyLists[manager.AssemblyLists.Count - 1];
} }
} }
} }
@ -372,7 +372,7 @@ namespace ICSharpCode.ILSpy.ViewModels
private void ExecuteSelectAssemblyList() private void ExecuteSelectAssemblyList()
{ {
MainWindow.Instance.sessionSettings.ActiveAssemblyList = SelectedAssemblyList; MainWindow.Instance.SessionSettings.ActiveAssemblyList = SelectedAssemblyList;
this.parent.Close(); this.parent.Close();
} }
} }

59
ILSpy/ViewModels/TabPageModel.cs

@ -27,61 +27,36 @@ namespace ICSharpCode.ILSpy.ViewModels
{ {
public class TabPageModel : PaneModel public class TabPageModel : PaneModel
{ {
private readonly Dictionary<Language, LanguageVersion> languageVersionHistory = new Dictionary<Language, LanguageVersion>();
public TabPageModel() public TabPageModel()
{ {
this.Title = Properties.Resources.NewTab; this.Title = Properties.Resources.NewTab;
} }
private Language language; private FilterSettings filterSettings;
public Language Language {
get => language; public FilterSettings FilterSettings {
get => filterSettings;
set { set {
if (language != value) if (filterSettings != value)
{ {
if (language != null && language.HasLanguageVersions) filterSettings = value;
{ RaisePropertyChanged(nameof(FilterSettings));
languageVersionHistory[language] = languageVersion;
}
language = value;
RaisePropertyChanged(nameof(Language));
if (language.HasLanguageVersions)
{
if (languageVersionHistory.TryGetValue(value, out var version))
{
LanguageVersion = version;
}
else
{
LanguageVersion = Language.LanguageVersions.Last();
}
}
else
{
LanguageVersion = default;
}
} }
} }
} }
private LanguageVersion languageVersion; public Language Language {
get => filterSettings.Language;
set => filterSettings.Language = value;
}
public LanguageVersion LanguageVersion { public LanguageVersion LanguageVersion {
get => languageVersion; get => filterSettings.LanguageVersion;
set { set => filterSettings.LanguageVersion = value;
if (languageVersion != value)
{
languageVersion = value;
if (language.HasLanguageVersions)
{
languageVersionHistory[language] = languageVersion;
}
RaisePropertyChanged(nameof(LanguageVersion));
}
}
} }
private bool supportsLanguageSwitching = true; private bool supportsLanguageSwitching = true;
public bool SupportsLanguageSwitching { public bool SupportsLanguageSwitching {
get => supportsLanguageSwitching; get => supportsLanguageSwitching;
set { set {
@ -94,6 +69,7 @@ namespace ICSharpCode.ILSpy.ViewModels
} }
private object content; private object content;
public object Content { public object Content {
get => content; get => content;
set { set {
@ -120,6 +96,7 @@ namespace ICSharpCode.ILSpy.ViewModels
textView = new DecompilerTextView(); textView = new DecompilerTextView();
tabPage.Content = textView; tabPage.Content = textView;
} }
tabPage.Title = Properties.Resources.Decompiling;
return action(textView); return action(textView);
} }
@ -130,6 +107,7 @@ namespace ICSharpCode.ILSpy.ViewModels
textView = new DecompilerTextView(); textView = new DecompilerTextView();
tabPage.Content = textView; tabPage.Content = textView;
} }
tabPage.Title = Properties.Resources.Decompiling;
return action(textView); return action(textView);
} }
@ -140,6 +118,7 @@ namespace ICSharpCode.ILSpy.ViewModels
textView = new DecompilerTextView(); textView = new DecompilerTextView();
tabPage.Content = textView; tabPage.Content = textView;
} }
tabPage.Title = Properties.Resources.Decompiling;
action(textView); action(textView);
} }
} }

18
ILSpy/Views/DebugSteps.xaml.cs

@ -1,4 +1,5 @@
using System; using System;
using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -22,13 +23,16 @@ namespace ICSharpCode.ILSpy
#if DEBUG #if DEBUG
ILAstLanguage language; ILAstLanguage language;
#endif #endif
FilterSettings filterSettings;
public DebugSteps() public DebugSteps()
{ {
InitializeComponent(); InitializeComponent();
#if DEBUG #if DEBUG
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged; DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
this.filterSettings = MainWindow.Instance.SessionSettings.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
MainWindow.Instance.SelectionChanged += SelectionChanged; MainWindow.Instance.SelectionChanged += SelectionChanged;
writingOptions.PropertyChanged += WritingOptions_PropertyChanged; writingOptions.PropertyChanged += WritingOptions_PropertyChanged;
@ -41,6 +45,18 @@ namespace ICSharpCode.ILSpy
#endif #endif
} }
private void DockWorkspace_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
break;
}
}
private void WritingOptions_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void WritingOptions_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
DecompileAsync(lastSelectedStep); DecompileAsync(lastSelectedStep);

Loading…
Cancel
Save