diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
index fbe046ea4a..5a9e10884a 100644
--- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
@@ -26,7 +26,7 @@
namespace ICSharpCode.ILSpy.ReadyToRun
{
- [ExportOptionPage(Title = nameof(global::ILSpy.ReadyToRun.Properties.Resources.ReadyToRun), Order = 40)]
+ [ExportOptionPage(Order = 40)]
[PartCreationPolicy(CreationPolicy.NonShared)]
partial class ReadyToRunOptionPage : UserControl, IOptionPage
{
@@ -35,6 +35,8 @@ public ReadyToRunOptionPage()
InitializeComponent();
}
+ public string Title => global::ILSpy.ReadyToRun.Properties.Resources.ReadyToRun;
+
public void Load(ILSpySettings settings)
{
Options s = new Options();
diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
index 892c8ea4f6..d2f67fd5e8 100644
--- a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
+++ b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
@@ -26,7 +26,7 @@ namespace ICSharpCode.ILSpy.Options
///
/// Interaction logic for DecompilerSettingsPanel.xaml
///
- [ExportOptionPage(Title = nameof(Properties.Resources.Decompiler), Order = 10)]
+ [ExportOptionPage(Order = 10)]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal partial class DecompilerSettingsPanel : IOptionPage
{
@@ -35,6 +35,8 @@ public DecompilerSettingsPanel()
InitializeComponent();
}
+ public string Title => Properties.Resources.Decompiler;
+
public static Decompiler.DecompilerSettings LoadDecompilerSettings(ILSpySettings settings)
{
return ISettingsProvider.LoadDecompilerSettings(settings);
diff --git a/ILSpy/Options/DisplaySettingsPanel.xaml.cs b/ILSpy/Options/DisplaySettingsPanel.xaml.cs
index 95b56b4eeb..e7e38eea5f 100644
--- a/ILSpy/Options/DisplaySettingsPanel.xaml.cs
+++ b/ILSpy/Options/DisplaySettingsPanel.xaml.cs
@@ -34,7 +34,7 @@ namespace ICSharpCode.ILSpy.Options
///
/// Interaction logic for DisplaySettingsPanel.xaml
///
- [ExportOptionPage(Title = nameof(Properties.Resources.Display), Order = 20)]
+ [ExportOptionPage(Order = 20)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class DisplaySettingsPanel : UserControl, IOptionPage
{
@@ -67,6 +67,8 @@ public DisplaySettingsPanel()
);
}
+ public string Title => Properties.Resources.Display;
+
public void Load(ILSpySettings settings)
{
this.DataContext = LoadDisplaySettings(settings);
diff --git a/ILSpy/Options/MiscSettingsPanel.xaml.cs b/ILSpy/Options/MiscSettingsPanel.xaml.cs
index 8fc6ea04f2..349b8851d9 100644
--- a/ILSpy/Options/MiscSettingsPanel.xaml.cs
+++ b/ILSpy/Options/MiscSettingsPanel.xaml.cs
@@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.Options
///
/// Interaction logic for MiscSettingsPanel.xaml
///
- [ExportOptionPage(Title = nameof(Properties.Resources.Misc), Order = 30)]
+ [ExportOptionPage(Order = 30)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MiscSettingsPanel : UserControl, IOptionPage
{
@@ -36,6 +36,8 @@ public MiscSettingsPanel()
InitializeComponent();
}
+ public string Title => Properties.Resources.Misc;
+
public void Load(ILSpySettings settings)
{
this.DataContext = new MiscSettingsViewModel(SettingsService.Instance.MiscSettings);
diff --git a/ILSpy/Options/OptionsDialog.xaml b/ILSpy/Options/OptionsDialog.xaml
index 7dd6d38dfc..ce61021952 100644
--- a/ILSpy/Options/OptionsDialog.xaml
+++ b/ILSpy/Options/OptionsDialog.xaml
@@ -1,35 +1,43 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/ILSpy/Options/OptionsDialog.xaml.cs b/ILSpy/Options/OptionsDialog.xaml.cs
index 0222193747..5cf64b8f2c 100644
--- a/ILSpy/Options/OptionsDialog.xaml.cs
+++ b/ILSpy/Options/OptionsDialog.xaml.cs
@@ -18,103 +18,42 @@
using System;
using System.ComponentModel.Composition;
-using System.Linq;
-using System.Windows;
using System.Xml.Linq;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpyX.Settings;
-using TomsToolbox.Composition;
-
namespace ICSharpCode.ILSpy.Options
{
- public class TabItemViewModel
- {
- public TabItemViewModel(string header, UIElement content)
- {
- Header = header;
- Content = content;
- }
-
- public string Header { get; }
-
- public UIElement Content { get; }
- }
-
///
/// Interaction logic for OptionsDialog.xaml
///
- public partial class OptionsDialog : Window
+ public sealed partial class OptionsDialog
{
- readonly IExport[] optionPages;
-
public OptionsDialog()
{
+ DataContext = new OptionsDialogViewModel();
InitializeComponent();
- var ep = App.ExportProvider;
- this.optionPages = ep.GetExports("OptionPages").ToArray();
- ILSpySettings settings = SettingsService.Instance.SpySettings;
- foreach (var optionPage in optionPages.OrderBy(p => p.Metadata.Order))
- {
- var tabItem = new TabItemViewModel(Util.ResourceHelper.GetString(optionPage.Metadata.Title), optionPage.Value);
-
- tabControl.Items.Add(tabItem);
-
- IOptionPage page = optionPage.Value as IOptionPage;
- if (page != null)
- page.Load(settings);
- }
- }
-
- void OKButton_Click(object sender, RoutedEventArgs e)
- {
- SettingsService.Instance.SpySettings.Update(
- root => {
- foreach (var optionPage in optionPages)
- {
- IOptionPage page = optionPage.Value as IOptionPage;
- if (page != null)
- page.Save(root);
- }
- });
- this.DialogResult = true;
- Close();
- }
-
- private void DefaultsButton_Click(object sender, RoutedEventArgs e)
- {
- if (MessageBox.Show(Properties.Resources.ResetToDefaultsConfirmationMessage, "ILSpy", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
- {
- var page = tabControl.SelectedValue as IOptionPage;
- if (page != null)
- page.LoadDefaults();
- }
}
}
public interface IOptionsMetadata
{
- string Title { get; }
int Order { get; }
}
public interface IOptionPage
{
+ string Title { get; }
void Load(ILSpySettings settings);
void Save(XElement root);
void LoadDefaults();
}
[MetadataAttribute]
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
- public class ExportOptionPageAttribute : ExportAttribute
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class ExportOptionPageAttribute() : ExportAttribute("OptionPages", typeof(IOptionPage)), IOptionsMetadata
{
- public ExportOptionPageAttribute() : base("OptionPages", typeof(UIElement))
- { }
-
- public string Title { get; set; }
-
public int Order { get; set; }
}
@@ -125,7 +64,7 @@ sealed class ShowOptionsCommand : SimpleCommand
public override void Execute(object parameter)
{
OptionsDialog dlg = new() {
- Owner = MainWindow.Instance
+ Owner = MainWindow.Instance,
};
if (dlg.ShowDialog() == true)
{
diff --git a/ILSpy/Options/OptionsDialogViewModel.cs b/ILSpy/Options/OptionsDialogViewModel.cs
new file mode 100644
index 0000000000..f78faeb9b1
--- /dev/null
+++ b/ILSpy/Options/OptionsDialogViewModel.cs
@@ -0,0 +1,71 @@
+using System.Linq;
+using System.Windows;
+using System.Windows.Input;
+
+using TomsToolbox.Essentials;
+using TomsToolbox.Wpf;
+
+#nullable enable
+
+namespace ICSharpCode.ILSpy.Options
+{
+ public class OptionsItemViewModel(IOptionPage content) : ObservableObject
+ {
+ public string Title { get; } = content.Title;
+
+ public IOptionPage Content { get; } = content;
+ }
+
+ public class OptionsDialogViewModel : ObservableObject
+ {
+ private IOptionPage? selectedPage;
+
+ private readonly IOptionPage[] optionPages = App.ExportProvider.GetExports("OptionPages")
+ .OrderBy(page => page.Metadata?.Order)
+ .Select(item => item.Value)
+ .ExceptNullItems()
+ .ToArray();
+
+ public OptionsDialogViewModel()
+ {
+ var settings = SettingsService.Instance.SpySettings;
+
+ foreach (var optionPage in optionPages)
+ {
+ optionPage.Load(settings);
+ }
+
+ OptionPages = optionPages.Select(page => new OptionsItemViewModel(page)).ToArray();
+ SelectedPage = optionPages.FirstOrDefault();
+ }
+
+ public OptionsItemViewModel[] OptionPages { get; }
+
+ public IOptionPage? SelectedPage {
+ get => selectedPage;
+ set => SetProperty(ref selectedPage, value);
+ }
+
+ public ICommand CommitCommand => new DelegateCommand(Commit);
+
+ public ICommand ResetDefaultsCommand => new DelegateCommand(ResetDefaults);
+
+ private void ResetDefaults()
+ {
+ if (MessageBox.Show(Properties.Resources.ResetToDefaultsConfirmationMessage, "ILSpy", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ SelectedPage?.LoadDefaults();
+ }
+ }
+
+ private void Commit()
+ {
+ SettingsService.Instance.SpySettings.Update(root => {
+ foreach (var optionPage in optionPages)
+ {
+ optionPage.Save(root);
+ }
+ });
+ }
+ }
+}
diff --git a/TestPlugin/CustomOptionPage.xaml.cs b/TestPlugin/CustomOptionPage.xaml.cs
index 9c38af296b..b90d817ca0 100644
--- a/TestPlugin/CustomOptionPage.xaml.cs
+++ b/TestPlugin/CustomOptionPage.xaml.cs
@@ -6,13 +6,12 @@
using System.Windows.Controls;
using System.Xml.Linq;
-using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpyX.Settings;
namespace TestPlugin
{
- [ExportOptionPage(Title = "TestPlugin", Order = 0)]
+ [ExportOptionPage(Order = 0)]
[PartCreationPolicy(CreationPolicy.NonShared)]
partial class CustomOptionPage : UserControl, IOptionPage
{
@@ -23,6 +22,8 @@ public CustomOptionPage()
InitializeComponent();
}
+ public string Title => "TestPlugin";
+
public void Load(ILSpySettings settings)
{
// For loading options, use ILSpySetting's indexer.