Browse Source

Introduce message bus to start decoupling components

pull/3257/head
tom-englert 9 months ago
parent
commit
cc7de5fe60
  1. 45
      .editorconfig
  2. 2
      ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs
  3. 37
      ILSpy/Analyzers/AnalyzeCommand.cs
  4. 21
      ILSpy/Analyzers/AnalyzerTreeView.cs
  5. 53
      ILSpy/Docking/DockWorkspace.cs
  6. 18
      ILSpy/Docking/TabPageGuardConverter.cs
  7. 9
      ILSpy/MainWindow.xaml
  8. 44
      ILSpy/MainWindow.xaml.cs
  9. 3
      ILSpy/Search/SearchPane.cs
  10. 55
      ILSpy/Util/MessageBus.cs
  11. 16
      ILSpy/Views/DebugSteps.xaml.cs

45
.editorconfig

@ -120,6 +120,51 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false @@ -120,6 +120,51 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Naming rules
dotnet_naming_rule.constants_rule.severity = warning
dotnet_naming_rule.constants_rule.style = upper_camel_case_style
dotnet_naming_rule.constants_rule.symbols = constants_symbols
dotnet_naming_rule.private_constants_rule.severity = warning
dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style
dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
dotnet_naming_rule.private_instance_fields_rule.severity = warning
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
dotnet_naming_rule.private_static_fields_rule.severity = warning
dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
dotnet_naming_rule.private_static_readonly_rule.severity = warning
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols
dotnet_naming_rule.public_static_fields_rule.severity = warning
dotnet_naming_rule.public_static_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.public_static_fields_rule.symbols = public_static_fields_symbols
dotnet_naming_rule.static_readonly_rule.severity = warning
dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style
dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.constants_symbols.applicable_kinds = field
dotnet_naming_symbols.constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = readonly,static
dotnet_naming_symbols.public_static_fields_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.public_static_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.public_static_fields_symbols.required_modifiers = static
dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.static_readonly_symbols.required_modifiers = readonly,static
# Errors and warnings
# MEF006: No importing constructor

2
ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs

@ -182,7 +182,7 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -182,7 +182,7 @@ namespace ICSharpCode.ILSpyX.TreeView
#endregion
#region OnChildrenChanged
internal protected virtual void OnChildrenChanged(NotifyCollectionChangedEventArgs e)
protected internal virtual void OnChildrenChanged(NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{

37
ILSpy/Analyzers/AnalyzeCommand.cs

@ -18,27 +18,18 @@ @@ -18,27 +18,18 @@
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;
using TomsToolbox.Composition;
namespace ICSharpCode.ILSpy.Analyzers
{
[ExportContextMenuEntry(Header = nameof(Resources.Analyze), Icon = "Images/Search", Category = nameof(Resources.Analyze), InputGestureText = "Ctrl+R", Order = 100)]
[PartCreationPolicy(CreationPolicy.Shared)]
internal sealed class AnalyzeCommand : SimpleCommand, IContextMenuEntry
{
private static readonly IExport<AnalyzerTreeView> analyzerTreeViewExport = App.ExportProvider.GetExports<AnalyzerTreeView>().Single();
private static AnalyzerTreeView AnalyzerTreeView {
get {
return Application.Current?.MainWindow?.IsLoaded != true ? null : analyzerTreeViewExport.Value;
}
}
private static readonly AnalyzerTreeView AnalyzerTreeView = App.ExportProvider.GetExportedValue<AnalyzerTreeView>();
public bool IsVisible(TextViewContext context)
{
@ -60,17 +51,13 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -60,17 +51,13 @@ namespace ICSharpCode.ILSpy.Analyzers
.All(node => IsValidReference(node.Member));
}
bool IsValidReference(object reference)
static bool IsValidReference(object reference)
{
return reference is IEntity && !(reference is IField f && f.IsConst);
return reference is IEntity and not IField { IsConst: true };
}
public void Execute(TextViewContext context)
{
if (AnalyzerTreeView is null)
{
return;
}
if (context.SelectedTreeNodes != null)
{
foreach (var node in context.SelectedTreeNodes.OfType<IMemberTreeNode>().ToArray())
@ -86,25 +73,13 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -86,25 +73,13 @@ namespace ICSharpCode.ILSpy.Analyzers
public override bool CanExecute(object parameter)
{
if (AnalyzerTreeView is null)
{
return false;
}
if (AnalyzerTreeView is { IsKeyboardFocusWithin: true })
{
return AnalyzerTreeView.SelectedItems.OfType<object>().All(n => n is IMemberTreeNode);
}
return MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode);
return AnalyzerTreeView.IsKeyboardFocusWithin
? AnalyzerTreeView.SelectedItems.OfType<object>().All(n => n is IMemberTreeNode)
: MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode);
}
public override void Execute(object parameter)
{
if (AnalyzerTreeView is null)
{
return;
}
if (AnalyzerTreeView.IsKeyboardFocusWithin)
{
foreach (var node in AnalyzerTreeView.SelectedItems.OfType<IMemberTreeNode>().ToArray())

21
ILSpy/Analyzers/AnalyzerTreeView.cs

@ -29,6 +29,7 @@ using ICSharpCode.ILSpy.Docking; @@ -29,6 +29,7 @@ using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpy.Controls.TreeView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Wpf.Composition.Mef;
@ -48,25 +49,21 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -48,25 +49,21 @@ namespace ICSharpCode.ILSpy.Analyzers
public AnalyzerTreeView()
{
this.ShowRoot = false;
this.Root = new AnalyzerRootNode { Language = MainWindow.Instance.CurrentLanguage };
this.BorderThickness = new Thickness(0);
ContextMenuProvider.Add(this);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
MessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => MainWindow_Instance_CurrentAssemblyListChanged(sender, e);
MessageBus<DockWorkspaceActiveTabPageChangedEventArgs>.Subscribers += DockWorkspace_ActiveTabPageChanged;
filterSettings = MainWindow.Instance.SessionSettings.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
}
private void DockWorkspace_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
private void DockWorkspace_ActiveTabPageChanged(object sender, EventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
break;
}
this.Root ??= new AnalyzerRootNode { Language = MainWindow.Instance.CurrentLanguage };
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
}
private void FilterSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

53
ILSpy/Docking/DockWorkspace.cs

@ -36,23 +36,23 @@ using AvalonDock.Layout.Serialization; @@ -36,23 +36,23 @@ using AvalonDock.Layout.Serialization;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy.Docking
{
public class DockWorkspace : INotifyPropertyChanged, ILayoutUpdateStrategy
public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy
{
private SessionSettings sessionSettings;
public event PropertyChangedEventHandler PropertyChanged;
public static DockWorkspace Instance { get; private set; }
public static readonly DockWorkspace Instance = new();
internal DockWorkspace(MainWindow parent)
private DockWorkspace()
{
Instance = this;
this.TabPages.CollectionChanged += Documents_CollectionChanged;
parent.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
MessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => MainWindow_Instance_CurrentAssemblyListChanged(sender, e);
}
private void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e)
@ -118,31 +118,31 @@ namespace ICSharpCode.ILSpy.Docking @@ -118,31 +118,31 @@ namespace ICSharpCode.ILSpy.Docking
tool.IsVisible = false;
}
private TabPageModel _activeTabPage = null;
private TabPageModel activeTabPage = null;
public TabPageModel ActiveTabPage {
get {
return _activeTabPage;
return activeTabPage;
}
set {
if (_activeTabPage != value)
if (!SetProperty(ref activeTabPage, value))
{
return;
}
var state = value.GetState();
if (state != null)
{
_activeTabPage = value;
var state = value.GetState();
if (state != null)
if (state.DecompiledNodes != null)
{
if (state.DecompiledNodes != null)
{
MainWindow.Instance.SelectNodes(state.DecompiledNodes,
inNewTabPage: false, setFocus: true, changingActiveTab: true);
}
else
{
MainWindow.Instance.NavigateTo(new RequestNavigateEventArgs(state.ViewedUri, null));
}
MainWindow.Instance.SelectNodes(state.DecompiledNodes,
inNewTabPage: false, setFocus: true, changingActiveTab: true);
}
else
{
MainWindow.Instance.NavigateTo(new(state.ViewedUri, null));
}
RaisePropertyChanged(nameof(ActiveTabPage));
}
MessageBus.Send(this, new DockWorkspaceActiveTabPageChangedEventArgs());
}
}
@ -181,11 +181,6 @@ namespace ICSharpCode.ILSpy.Docking @@ -181,11 +181,6 @@ namespace ICSharpCode.ILSpy.Docking
}
}
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void ShowText(AvalonEditTextOutput textOutput)
{
ActiveTabPage.ShowTextView(textView => textView.ShowText(textOutput));

18
ILSpy/Docking/ActiveTabPageConverter.cs → ILSpy/Docking/TabPageGuardConverter.cs

@ -21,24 +21,20 @@ using System.Windows.Data; @@ -21,24 +21,20 @@ using System.Windows.Data;
using ICSharpCode.ILSpy.ViewModels;
using TomsToolbox.Wpf.Converters;
namespace ICSharpCode.ILSpy.Docking
{
public class ActiveTabPageConverter : IValueConverter
public class TabPageGuardConverter : ValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
protected override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is TabPageModel)
return value;
return Binding.DoNothing;
return value is TabPageModel ? value : Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
protected override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is TabPageModel)
return value;
return Binding.DoNothing;
return value is TabPageModel ? value : Binding.DoNothing;
}
}
}

9
ILSpy/MainWindow.xaml

@ -26,8 +26,6 @@ @@ -26,8 +26,6 @@
d:DataContext="{d:DesignInstance local:MainWindowViewModel}"
>
<Window.Resources>
<docking:ActiveTabPageConverter x:Key="ActiveTabPageConverter"/>
<tv:SharpTreeView x:Key="AssemblyTreeView"
AutomationProperties.Name="Assemblies and Classes"
SelectionChanged="TreeView_SelectionChanged"
@ -82,6 +80,7 @@ @@ -82,6 +80,7 @@
<controls:CultureSelectionConverter x:Key="cultureSelectionConverter" />
</Window.Resources>
<b:Interaction.Behaviors>
<themes:WindowStyleManagerBehavior />
</b:Interaction.Behaviors>
@ -109,12 +108,15 @@ @@ -109,12 +108,15 @@
Command="Search"
Executed="SearchCommandExecuted" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="R" Modifiers="Control" Command="{x:Static local:ILSpyCommands.Analyze}" />
</Window.InputBindings>
<Window.TaskbarItemInfo>
<TaskbarItemInfo />
</Window.TaskbarItemInfo>
<DockPanel>
<!-- Main menu -->
<Menu DockPanel.Dock="Top" Name="mainMenu" Height="23" KeyboardNavigation.TabNavigation="None">
@ -207,6 +209,7 @@ @@ -207,6 +209,7 @@
ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding Workspace.ActiveTabPage.FilterSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/>
</ToolBar>
<!-- Update panel -->
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1" Name="updatePanel" Visibility="Collapsed">
<DockPanel KeyboardNavigation.TabNavigation="Contained">
<Button DockPanel.Dock="Right" Click="updatePanelCloseButtonClick" MinWidth="0">X</Button>
@ -231,7 +234,7 @@ @@ -231,7 +234,7 @@
DataContext="{Binding Workspace}"
AnchorablesSource="{Binding ToolPanes}"
DocumentsSource="{Binding TabPages}"
ActiveContent="{Binding ActiveTabPage, Mode=TwoWay, Converter={StaticResource ActiveTabPageConverter}}"
ActiveContent="{Binding ActiveTabPage, Mode=TwoWay, Converter={docking:TabPageGuardConverter}}"
AllowMixedOrientation="True">
<avalondock:DockingManager.DocumentHeaderTemplate>

44
ILSpy/MainWindow.xaml.cs

@ -42,7 +42,6 @@ using ICSharpCode.Decompiler.Documentation; @@ -42,7 +42,6 @@ using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Commands;
using ICSharpCode.ILSpy.Docking;
@ -57,6 +56,7 @@ using ICSharpCode.ILSpyX; @@ -57,6 +56,7 @@ using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.FileLoaders;
using ICSharpCode.ILSpyX.Settings;
using ICSharpCode.ILSpy.Controls.TreeView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX.Extensions;
using Microsoft.Win32;
@ -130,7 +130,7 @@ namespace ICSharpCode.ILSpy @@ -130,7 +130,7 @@ namespace ICSharpCode.ILSpy
this.Icon = Images.ILSpyIcon;
this.DataContext = new MainWindowViewModel {
Workspace = new DockWorkspace(this),
Workspace = DockWorkspace.Instance,
SessionSettings = sessionSettings,
AssemblyListManager = AssemblyListManager
};
@ -147,7 +147,7 @@ namespace ICSharpCode.ILSpy @@ -147,7 +147,7 @@ namespace ICSharpCode.ILSpy
sessionSettings.PropertyChanged += SessionSettings_PropertyChanged;
filterSettings = sessionSettings.FilterSettings;
filterSettings.PropertyChanged += filterSettings_PropertyChanged;
DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
MessageBus<DockWorkspaceActiveTabPageChangedEventArgs>.Subscribers += DockWorkspace_ActiveTabPageChanged;
InitMainMenu();
InitWindowMenu();
InitToolbar();
@ -157,25 +157,20 @@ namespace ICSharpCode.ILSpy @@ -157,25 +157,20 @@ namespace ICSharpCode.ILSpy
this.Loaded += MainWindow_Loaded;
}
private void DockWorkspace_PropertyChanged(object sender, PropertyChangedEventArgs e)
private void DockWorkspace_ActiveTabPageChanged(object sender, EventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
DockWorkspace dock = DockWorkspace.Instance;
filterSettings.PropertyChanged -= filterSettings_PropertyChanged;
filterSettings = dock.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += filterSettings_PropertyChanged;
DockWorkspace dock = DockWorkspace.Instance;
filterSettings.PropertyChanged -= filterSettings_PropertyChanged;
filterSettings = dock.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += filterSettings_PropertyChanged;
var windowMenuItem = mainMenu.Items.OfType<MenuItem>().First(m => (string)m.Tag == nameof(Properties.Resources._Window));
foreach (MenuItem menuItem in windowMenuItem.Items.OfType<MenuItem>())
{
if (menuItem.IsCheckable && menuItem.Tag is TabPageModel)
{
menuItem.IsChecked = menuItem.Tag == dock.ActiveTabPage;
}
}
break;
var windowMenuItem = mainMenu.Items.OfType<MenuItem>().First(m => (string)m.Tag == nameof(Properties.Resources._Window));
foreach (MenuItem menuItem in windowMenuItem.Items.OfType<MenuItem>())
{
if (menuItem.IsCheckable && menuItem.Tag is TabPageModel)
{
menuItem.IsChecked = menuItem.Tag == dock.ActiveTabPage;
}
}
}
@ -359,7 +354,7 @@ namespace ICSharpCode.ILSpy @@ -359,7 +354,7 @@ namespace ICSharpCode.ILSpy
#endregion
#region Tool Pane extensibility
private void InitToolPanes()
{
var toolPanes = App.ExportProvider.GetExportedValues<ToolPaneModel>("ToolPane");
@ -632,8 +627,6 @@ namespace ICSharpCode.ILSpy @@ -632,8 +627,6 @@ namespace ICSharpCode.ILSpy
get { return assemblyList; }
}
public event NotifyCollectionChangedEventHandler CurrentAssemblyListChanged;
List<LoadedAssembly> commandLineLoadedAssemblies = new List<LoadedAssembly>();
internal async Task HandleSingleInstanceCommandLineArguments(string[] args)
@ -1038,7 +1031,8 @@ namespace ICSharpCode.ILSpy @@ -1038,7 +1031,8 @@ namespace ICSharpCode.ILSpy
nd => nd.AncestorsAndSelf().OfType<AssemblyTreeNode>().Any(
a => oldAssemblies.Contains(a.LoadedAssembly))));
}
CurrentAssemblyListChanged?.Invoke(this, e);
MessageBus.Send(this, new CurrentAssemblyListChangedEventArgs(e));
}
void LoadInitialAssemblies()
@ -1528,8 +1522,6 @@ namespace ICSharpCode.ILSpy @@ -1528,8 +1522,6 @@ namespace ICSharpCode.ILSpy
public Language CurrentLanguage => DockWorkspace.Instance.ActiveTabPage.FilterSettings.Language;
public LanguageVersion CurrentLanguageVersion => DockWorkspace.Instance.ActiveTabPage.FilterSettings.LanguageVersion;
public bool SupportsLanguageSwitching => DockWorkspace.Instance.ActiveTabPage.SupportsLanguageSwitching;
public event SelectionChangedEventHandler SelectionChanged;
public IEnumerable<ILSpyTreeNode> SelectedNodes {

3
ILSpy/Search/SearchPane.cs

@ -35,6 +35,7 @@ using System.Windows.Threading; @@ -35,6 +35,7 @@ using System.Windows.Threading;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Extensions;
@ -82,7 +83,7 @@ namespace ICSharpCode.ILSpy.Search @@ -82,7 +83,7 @@ namespace ICSharpCode.ILSpy.Search
searchModeComboBox.Items.Add(new { Image = Images.Namespace, Name = "Namespace" });
ContextMenuProvider.Add(listBox);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
MessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => MainWindow_Instance_CurrentAssemblyListChanged(sender, e);
filterSettings = MainWindow.Instance.SessionSettings.FilterSettings;
CompositionTarget.Rendering += UpdateResults;

55
ILSpy/Util/MessageBus.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
using System;
using System.Collections.Specialized;
using TomsToolbox.Essentials;
namespace ICSharpCode.ILSpy.Util
{
public static class MessageBus
{
public static void Send<T>(object sender, T e)
where T : EventArgs
{
MessageBus<T>.Send(sender, e);
}
}
/// <summary>
/// Simple, minimalistic message bus.
/// </summary>
/// <typeparam name="T">The type of the message event arguments</typeparam>
public static class MessageBus<T>
where T : EventArgs
{
private static readonly WeakEventSource<T> Subscriptions = new();
public static event EventHandler<T> Subscribers {
add => Subscriptions.Subscribe(value);
remove => Subscriptions.Unsubscribe(value);
}
public static void Send(object sender, T e)
{
Subscriptions.Raise(sender, e);
}
}
public abstract class WrappedEventArgs<T> : EventArgs
{
private readonly T inner;
protected WrappedEventArgs(T inner)
{
this.inner = inner;
}
public static implicit operator T(WrappedEventArgs<T> outer)
{
return outer.inner;
}
}
public class CurrentAssemblyListChangedEventArgs(NotifyCollectionChangedEventArgs e) : WrappedEventArgs<NotifyCollectionChangedEventArgs>(e);
public class DockWorkspaceActiveTabPageChangedEventArgs : EventArgs;
}

16
ILSpy/Views/DebugSteps.xaml.cs

@ -8,6 +8,7 @@ using System.Windows.Input; @@ -8,6 +8,7 @@ using System.Windows.Input;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using TomsToolbox.Wpf.Composition.Mef;
@ -35,7 +36,7 @@ namespace ICSharpCode.ILSpy @@ -35,7 +36,7 @@ namespace ICSharpCode.ILSpy
InitializeComponent();
#if DEBUG
DockWorkspace.Instance.PropertyChanged += DockWorkspace_PropertyChanged;
MessageBus<DockWorkspaceActiveTabPageChangedEventArgs>.Subscribers += DockWorkspace_ActiveTabPageChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
MainWindow.Instance.SelectionChanged += SelectionChanged;
@ -50,16 +51,11 @@ namespace ICSharpCode.ILSpy @@ -50,16 +51,11 @@ namespace ICSharpCode.ILSpy
#endif
}
private void DockWorkspace_PropertyChanged(object sender, PropertyChangedEventArgs e)
private void DockWorkspace_ActiveTabPageChanged(object sender, EventArgs e)
{
switch (e.PropertyName)
{
case nameof(DockWorkspace.Instance.ActiveTabPage):
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
break;
}
filterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
filterSettings = DockWorkspace.Instance.ActiveTabPage.FilterSettings;
filterSettings.PropertyChanged += FilterSettings_PropertyChanged;
}
private void WritingOptions_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

Loading…
Cancel
Save