From d4df855e01537a2974844e6aaad3f88c4f823ead Mon Sep 17 00:00:00 2001 From: tom-englert Date: Mon, 19 Aug 2024 14:09:54 +0200 Subject: [PATCH] Refactor AnalyzerTreeView into View/ViewModel --- ILSpy/Analyzers/AnalyzeCommand.cs | 27 ++- ILSpy/Analyzers/AnalyzerRootNode.cs | 42 +++++ ILSpy/Analyzers/AnalyzerTreeView.cs | 158 ------------------ ILSpy/Analyzers/AnalyzerTreeView.xaml | 23 +++ .../AnalyzerTreeView.xaml.cs} | 36 ++-- ILSpy/Analyzers/AnalyzerTreeViewModel.cs | 130 ++++++++++++++ ILSpy/Docking/DockWorkspace.cs | 18 +- ILSpy/MainWindow.xaml | 2 +- ILSpy/MainWindow.xaml.cs | 3 +- ILSpy/ViewModels/PaneModel.cs | 25 ++- ILSpy/ViewModels/TabPageModel.cs | 4 +- 11 files changed, 250 insertions(+), 218 deletions(-) create mode 100644 ILSpy/Analyzers/AnalyzerRootNode.cs delete mode 100644 ILSpy/Analyzers/AnalyzerTreeView.cs create mode 100644 ILSpy/Analyzers/AnalyzerTreeView.xaml rename ILSpy/{ViewModels/AnalyzerPaneModel.cs => Analyzers/AnalyzerTreeView.xaml.cs} (61%) create mode 100644 ILSpy/Analyzers/AnalyzerTreeViewModel.cs diff --git a/ILSpy/Analyzers/AnalyzeCommand.cs b/ILSpy/Analyzers/AnalyzeCommand.cs index d6cf8a7e91..889e6afa0b 100644 --- a/ILSpy/Analyzers/AnalyzeCommand.cs +++ b/ILSpy/Analyzers/AnalyzeCommand.cs @@ -27,9 +27,9 @@ 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 + internal sealed class AnalyzeContextMenuCommand : IContextMenuEntry { - private static readonly AnalyzerTreeView AnalyzerTreeView = App.ExportProvider.GetExportedValue(); + private static readonly AnalyzerTreeViewModel AnalyzerTreeView = App.ExportProvider.GetExportedValue(); public bool IsVisible(TextViewContext context) { @@ -70,29 +70,22 @@ public void Execute(TextViewContext context) AnalyzerTreeView.Analyze(entity); } } + } + + internal sealed class AnalyzeCommand : SimpleCommand + { + private static readonly AnalyzerTreeViewModel AnalyzerTreeView = App.ExportProvider.GetExportedValue(); public override bool CanExecute(object parameter) { - return AnalyzerTreeView.IsKeyboardFocusWithin - ? AnalyzerTreeView.SelectedItems.OfType().All(n => n is IMemberTreeNode) - : MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode); + return MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode); } public override void Execute(object parameter) { - if (AnalyzerTreeView.IsKeyboardFocusWithin) + foreach (var node in MainWindow.Instance.SelectedNodes.OfType()) { - foreach (var node in AnalyzerTreeView.SelectedItems.OfType().ToArray()) - { - AnalyzerTreeView.Analyze(node.Member); - } - } - else - { - foreach (var node in MainWindow.Instance.SelectedNodes.OfType()) - { - AnalyzerTreeView.Analyze(node.Member); - } + AnalyzerTreeView.Analyze(node.Member); } } } diff --git a/ILSpy/Analyzers/AnalyzerRootNode.cs b/ILSpy/Analyzers/AnalyzerRootNode.cs new file mode 100644 index 0000000000..17709687f9 --- /dev/null +++ b/ILSpy/Analyzers/AnalyzerRootNode.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; + +using ICSharpCode.ILSpy.Util; +using ICSharpCode.ILSpyX; +using ICSharpCode.ILSpyX.TreeView; + +namespace ICSharpCode.ILSpy.Analyzers; + +public sealed class AnalyzerRootNode : AnalyzerTreeNode +{ + public AnalyzerRootNode() + { + MessageBus.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e); + } + + void CurrentAssemblyList_Changed(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Reset) + { + this.Children.Clear(); + } + else + { + var removedAssemblies = e.OldItems?.Cast().ToArray() ?? []; + var addedAssemblies = e.NewItems?.Cast().ToArray() ?? []; + + HandleAssemblyListChanged(removedAssemblies, addedAssemblies); + } + } + + public override bool HandleAssemblyListChanged(ICollection removedAssemblies, ICollection addedAssemblies) + { + this.Children.RemoveAll( + delegate (SharpTreeNode n) { + AnalyzerTreeNode an = n as AnalyzerTreeNode; + return an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies); + }); + return true; + } +} \ No newline at end of file diff --git a/ILSpy/Analyzers/AnalyzerTreeView.cs b/ILSpy/Analyzers/AnalyzerTreeView.cs deleted file mode 100644 index 97b65b6f34..0000000000 --- a/ILSpy/Analyzers/AnalyzerTreeView.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel.Composition; -using System.Linq; -using System.Windows; - -using ICSharpCode.Decompiler.TypeSystem; -using ICSharpCode.ILSpy.Analyzers.TreeNodes; -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; - -namespace ICSharpCode.ILSpy.Analyzers -{ - /// - /// Analyzer tree view. - /// - [DataTemplate(typeof(AnalyzerPaneModel))] - [PartCreationPolicy(CreationPolicy.Shared)] - [Export] - public class AnalyzerTreeView : SharpTreeView - { - public AnalyzerTreeView() - { - this.ShowRoot = false; - this.BorderThickness = new(); - this.Root = new AnalyzerRootNode(); - ContextMenuProvider.Add(this); - } - - public void Show() - { - DockWorkspace.Instance.ShowToolPane(AnalyzerPaneModel.PaneContentId); - } - - public void Show(AnalyzerTreeNode node) - { - Show(); - - node.IsExpanded = true; - this.Root.Children.Add(node); - this.SelectedItem = node; - this.FocusNode(node); - } - - public void ShowOrFocus(AnalyzerTreeNode node) - { - if (node is AnalyzerEntityTreeNode) - { - var an = node as AnalyzerEntityTreeNode; - var found = this.Root.Children.OfType().FirstOrDefault(n => n.Member == an.Member); - if (found != null) - { - Show(); - - found.IsExpanded = true; - this.SelectedItem = found; - this.FocusNode(found); - return; - } - } - Show(node); - } - - public void Analyze(IEntity entity) - { - if (entity == null) - { - throw new ArgumentNullException(nameof(entity)); - } - - if (entity.MetadataToken.IsNil) - { - MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy"); - return; - } - - switch (entity) - { - case ITypeDefinition td: - ShowOrFocus(new AnalyzedTypeTreeNode(td)); - break; - case IField fd: - if (!fd.IsConst) - ShowOrFocus(new AnalyzedFieldTreeNode(fd)); - break; - case IMethod md: - ShowOrFocus(new AnalyzedMethodTreeNode(md)); - break; - case IProperty pd: - ShowOrFocus(new AnalyzedPropertyTreeNode(pd)); - break; - case IEvent ed: - ShowOrFocus(new AnalyzedEventTreeNode(ed)); - break; - default: - throw new ArgumentOutOfRangeException(nameof(entity), $"Entity {entity.GetType().FullName} is not supported."); - } - } - - sealed class AnalyzerRootNode : AnalyzerTreeNode - { - public AnalyzerRootNode() - { - MessageBus.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e); - } - - void CurrentAssemblyList_Changed(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.Action == NotifyCollectionChangedAction.Reset) - { - this.Children.Clear(); - } - else - { - var removedAssemblies = e.OldItems?.Cast().ToArray() ?? []; - var addedAssemblies = e.NewItems?.Cast().ToArray() ?? []; - - HandleAssemblyListChanged(removedAssemblies, addedAssemblies); - } - } - - public override bool HandleAssemblyListChanged(ICollection removedAssemblies, ICollection addedAssemblies) - { - this.Children.RemoveAll( - delegate (SharpTreeNode n) { - AnalyzerTreeNode an = n as AnalyzerTreeNode; - return an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies); - }); - return true; - } - } - } -} diff --git a/ILSpy/Analyzers/AnalyzerTreeView.xaml b/ILSpy/Analyzers/AnalyzerTreeView.xaml new file mode 100644 index 0000000000..28bba030c8 --- /dev/null +++ b/ILSpy/Analyzers/AnalyzerTreeView.xaml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/ILSpy/ViewModels/AnalyzerPaneModel.cs b/ILSpy/Analyzers/AnalyzerTreeView.xaml.cs similarity index 61% rename from ILSpy/ViewModels/AnalyzerPaneModel.cs rename to ILSpy/Analyzers/AnalyzerTreeView.xaml.cs index ca92e5dae5..bff239a460 100644 --- a/ILSpy/ViewModels/AnalyzerPaneModel.cs +++ b/ILSpy/Analyzers/AnalyzerTreeView.xaml.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -17,22 +17,34 @@ // DEALINGS IN THE SOFTWARE. using System.ComponentModel.Composition; -using System.Windows.Input; +using System.Windows.Controls; -namespace ICSharpCode.ILSpy.ViewModels +using ICSharpCode.ILSpyX.TreeView; + +using TomsToolbox.Wpf.Composition.Mef; + +namespace ICSharpCode.ILSpy.Analyzers { - [ExportToolPane] - [PartCreationPolicy(CreationPolicy.Shared)] - public class AnalyzerPaneModel : ToolPaneModel + /// + /// Interaction logic for AnalyzerTreeView.xaml + /// + [DataTemplate(typeof(AnalyzerTreeViewModel))] + [PartCreationPolicy(CreationPolicy.NonShared)] + [Export] + public partial class AnalyzerTreeView { - public const string PaneContentId = "analyzerPane"; + public AnalyzerTreeView() + { + InitializeComponent(); + ContextMenuProvider.Add(this); + } - public AnalyzerPaneModel() + private void AnalyzerTreeView_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { - ContentId = PaneContentId; - Title = Properties.Resources.Analyze; - ShortcutKey = new KeyGesture(Key.R, ModifierKeys.Control); - AssociatedCommand = ILSpyCommands.Analyze; + if (SelectedItem is SharpTreeNode sharpTreeNode) + { + FocusNode(sharpTreeNode); + } } } } diff --git a/ILSpy/Analyzers/AnalyzerTreeViewModel.cs b/ILSpy/Analyzers/AnalyzerTreeViewModel.cs new file mode 100644 index 0000000000..fc7def7558 --- /dev/null +++ b/ILSpy/Analyzers/AnalyzerTreeViewModel.cs @@ -0,0 +1,130 @@ +// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel.Composition; +using System.Linq; +using System.Windows; +using System.Windows.Input; + +using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.ILSpy.Analyzers.TreeNodes; +using ICSharpCode.ILSpy.TreeNodes; +using ICSharpCode.ILSpy.ViewModels; + +using TomsToolbox.Wpf; + +namespace ICSharpCode.ILSpy.Analyzers +{ + [ExportToolPane] + [PartCreationPolicy(CreationPolicy.Shared)] + [Export] + public class AnalyzerTreeViewModel : ToolPaneModel + { + private AnalyzerTreeNode selectedItem; + + public const string PaneContentId = "analyzerPane"; + + public AnalyzerTreeViewModel() + { + ContentId = PaneContentId; + Title = Properties.Resources.Analyze; + ShortcutKey = new(Key.R, ModifierKeys.Control); + AssociatedCommand = ILSpyCommands.Analyze; + } + + public AnalyzerRootNode Root { get; } = new(); + + public AnalyzerTreeNode SelectedItem { + get => selectedItem; + set => SetProperty(ref selectedItem, value); + } + + public ICommand AnalyzeCommand => new DelegateCommand(AnalyzeSelected); + + public ObservableCollection SelectedItems { get; } = []; + + private void AnalyzeSelected() + { + foreach (var node in SelectedItems.OfType()) + { + Analyze(node.Member); + } + } + + void AddOrSelect(AnalyzerTreeNode node) + { + Show(); + + AnalyzerTreeNode target = default; + + if (node is AnalyzerEntityTreeNode { Member: { } member }) + { + target = this.Root.Children.OfType().FirstOrDefault(item => item.Member == member); + } + + if (target == null) + { + this.Root.Children.Add(node); + target = node; + } + + target.IsExpanded = true; + this.SelectedItem = target; + } + + public void Analyze(IEntity entity) + { + if (entity == null) + { + throw new ArgumentNullException(nameof(entity)); + } + + if (entity.MetadataToken.IsNil) + { + MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy"); + return; + } + + switch (entity) + { + case ITypeDefinition td: + AddOrSelect(new AnalyzedTypeTreeNode(td)); + break; + case IField fd: + if (!fd.IsConst) + AddOrSelect(new AnalyzedFieldTreeNode(fd)); + break; + case IMethod md: + AddOrSelect(new AnalyzedMethodTreeNode(md)); + break; + case IProperty pd: + AddOrSelect(new AnalyzedPropertyTreeNode(pd)); + break; + case IEvent ed: + AddOrSelect(new AnalyzedEventTreeNode(ed)); + break; + default: + throw new ArgumentOutOfRangeException(nameof(entity), $@"Entity {entity.GetType().FullName} is not supported."); + } + } + } +} + diff --git a/ILSpy/Docking/DockWorkspace.cs b/ILSpy/Docking/DockWorkspace.cs index 0a4c8fe711..6ae7a0bdce 100644 --- a/ILSpy/Docking/DockWorkspace.cs +++ b/ILSpy/Docking/DockWorkspace.cs @@ -35,6 +35,7 @@ using AvalonDock.Layout.Serialization; using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.ILSpy.Analyzers; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.Util; using ICSharpCode.ILSpy.ViewModels; @@ -45,17 +46,17 @@ namespace ICSharpCode.ILSpy.Docking { public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy { - private SessionSettings sessionSettings; + private static SessionSettings SessionSettings => SettingsService.Instance.SessionSettings; public static readonly DockWorkspace Instance = new(); private DockWorkspace() { this.TabPages.CollectionChanged += Documents_CollectionChanged; - MessageBus.Subscribers += (sender, e) => MainWindow_Instance_CurrentAssemblyListChanged(sender, e); + MessageBus.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e); } - private void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e) + private void CurrentAssemblyList_Changed(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems == null) { @@ -158,7 +159,7 @@ public void InitializeLayout(DockingManager manager) serializer.LayoutSerializationCallback += LayoutSerializationCallback; try { - sessionSettings.DockLayout.Deserialize(serializer); + SessionSettings.DockLayout.Deserialize(serializer); } finally { @@ -201,11 +202,6 @@ internal void ShowNodes(AvalonEditTextOutput output, TreeNodes.ILSpyTreeNode[] n ActiveTabPage.ShowTextView(textView => textView.ShowNodes(output, nodes, highlighting)); } - internal void LoadSettings(SessionSettings sessionSettings) - { - this.sessionSettings = sessionSettings; - } - internal void CloseAllTabs() { foreach (var doc in TabPages.ToArray()) @@ -222,7 +218,7 @@ internal void ResetLayout() pane.IsVisible = false; } CloseAllTabs(); - sessionSettings.DockLayout.Reset(); + SessionSettings.DockLayout.Reset(); InitializeLayout(MainWindow.Instance.DockManager); MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView); } @@ -243,7 +239,7 @@ public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorabl previousContainer.Children.Add(anchorableToShow); return true; case LegacyToolPaneLocation.Bottom: - previousContainer = GetContainer(); + previousContainer = GetContainer(); previousContainer.Children.Add(anchorableToShow); return true; default: diff --git a/ILSpy/MainWindow.xaml b/ILSpy/MainWindow.xaml index 32d7981eb1..a6650e05aa 100644 --- a/ILSpy/MainWindow.xaml +++ b/ILSpy/MainWindow.xaml @@ -35,7 +35,6 @@ BorderThickness="0" Visibility="Visible"> + diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index bebfd98628..810e70f99b 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -135,7 +135,6 @@ public MainWindow() { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(sessionSettings.CurrentCulture); } - DockWorkspace.Instance.LoadSettings(sessionSettings); InitializeComponent(); InitToolPanes(); DockWorkspace.Instance.InitializeLayout(DockManager); @@ -352,7 +351,7 @@ internal static string GetResourceString(string key) private void InitToolPanes() { - var toolPanes = App.ExportProvider.GetExportedValues("ToolPane"); + var toolPanes = App.ExportProvider.GetExportedValues("ToolPane").OrderBy(item => item.Title); DockWorkspace.Instance.ToolPanes.AddRange(toolPanes); } diff --git a/ILSpy/ViewModels/PaneModel.cs b/ILSpy/ViewModels/PaneModel.cs index b214c9d97c..c88bf869ac 100644 --- a/ILSpy/ViewModels/PaneModel.cs +++ b/ILSpy/ViewModels/PaneModel.cs @@ -20,9 +20,11 @@ using System.ComponentModel; using System.Windows.Input; +using TomsToolbox.Wpf; + namespace ICSharpCode.ILSpy.ViewModels { - public abstract class PaneModel : INotifyPropertyChanged + public abstract class PaneModel : ObservableObject { class CloseCommandImpl : ICommand { @@ -60,13 +62,6 @@ public PaneModel() this.closeCommand = new CloseCommandImpl(this); } - public event PropertyChangedEventHandler PropertyChanged; - - protected void RaisePropertyChanged(string propertyName) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - private bool isSelected = false; public bool IsSelected { get => isSelected; @@ -74,7 +69,7 @@ public bool IsSelected { if (isSelected != value) { isSelected = value; - RaisePropertyChanged(nameof(IsSelected)); + OnPropertyChanged(nameof(IsSelected)); } } } @@ -86,7 +81,7 @@ public bool IsActive { if (isActive != value) { isActive = value; - RaisePropertyChanged(nameof(IsActive)); + OnPropertyChanged(nameof(IsActive)); } } } @@ -98,7 +93,7 @@ public bool IsVisible { if (isVisible != value) { isVisible = value; - RaisePropertyChanged(nameof(IsVisible)); + OnPropertyChanged(nameof(IsVisible)); } } } @@ -110,7 +105,7 @@ public bool IsCloseable { if (isCloseable != value) { isCloseable = value; - RaisePropertyChanged(nameof(IsCloseable)); + OnPropertyChanged(nameof(IsCloseable)); } } } @@ -122,7 +117,7 @@ public ICommand CloseCommand { if (closeCommand != value) { closeCommand = value; - RaisePropertyChanged(nameof(CloseCommand)); + OnPropertyChanged(nameof(CloseCommand)); } } } @@ -134,7 +129,7 @@ public string ContentId { if (contentId != value) { contentId = value; - RaisePropertyChanged(nameof(ContentId)); + OnPropertyChanged(nameof(ContentId)); } } } @@ -146,7 +141,7 @@ public string Title { if (title != value) { title = value; - RaisePropertyChanged(nameof(Title)); + OnPropertyChanged(nameof(Title)); } } } diff --git a/ILSpy/ViewModels/TabPageModel.cs b/ILSpy/ViewModels/TabPageModel.cs index 71063243e8..10c28d47c0 100644 --- a/ILSpy/ViewModels/TabPageModel.cs +++ b/ILSpy/ViewModels/TabPageModel.cs @@ -40,7 +40,7 @@ public bool SupportsLanguageSwitching { if (supportsLanguageSwitching != value) { supportsLanguageSwitching = value; - RaisePropertyChanged(nameof(SupportsLanguageSwitching)); + OnPropertyChanged(nameof(SupportsLanguageSwitching)); } } } @@ -53,7 +53,7 @@ public object Content { if (content != value) { content = value; - RaisePropertyChanged(nameof(Content)); + OnPropertyChanged(nameof(Content)); } } }