diff --git a/Moder.Core/MainWindow.xaml.cs b/Moder.Core/MainWindow.xaml.cs index 771e812..cc613f3 100644 --- a/Moder.Core/MainWindow.xaml.cs +++ b/Moder.Core/MainWindow.xaml.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -8,6 +8,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; +using Moder.Core.Extensions; using Moder.Core.Messages; using Moder.Core.Services.Config; using Moder.Core.Views; @@ -145,9 +146,7 @@ private IFileView GetContent(SystemFileItem fileItem) private void MainWindow_OnClosed(object sender, WindowEventArgs args) { - _logger.LogInformation("配置文件保存中..."); - _settings.Save(); - _logger.LogInformation("配置文件保存完成"); + _settings.SaveChanged(); } private void MainTabView_OnTabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args) @@ -164,6 +163,10 @@ private void MainTabView_OnTabCloseRequested(TabView sender, TabViewTabCloseRequ WeakReferenceMessenger.Default.Send(new SyncSideWorkSelectedItemMessage(null)); } } + else if (args.Tab.Content is SettingsControlView settings) + { + settings.SaveChanged(); + } } private void MainTabView_OnSelectionChanged(object sender, SelectionChangedEventArgs e) diff --git a/Moder.Core/Services/Config/GlobalSettingService.cs b/Moder.Core/Services/Config/GlobalSettingService.cs index e72a160..fb4ec2f 100644 --- a/Moder.Core/Services/Config/GlobalSettingService.cs +++ b/Moder.Core/Services/Config/GlobalSettingService.cs @@ -1,4 +1,6 @@ -using MemoryPack; +using MemoryPack; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.UI.Xaml; using Moder.Core.Models; @@ -8,24 +10,75 @@ namespace Moder.Core.Services.Config; public sealed partial class GlobalSettingService { [MemoryPackOrder(0)] - public string ModRootFolderPath { get; set; } = string.Empty; + public string ModRootFolderPath + { + get => _modRootFolderPath; + set => SetProperty(ref _modRootFolderPath, value); + } + private string _modRootFolderPath = string.Empty; [MemoryPackOrder(1)] - public string GameRootFolderPath { get; set; } = string.Empty; + public string GameRootFolderPath + { + get => _gameRootFolderPath; + set => SetProperty(ref _gameRootFolderPath, value); + } + private string _gameRootFolderPath = string.Empty; [MemoryPackOrder(2)] - public ElementTheme AppThemeMode { get; set; } = ElementTheme.Default; + public ElementTheme AppThemeMode + { + get => _appThemeMode; + set => SetProperty(ref _appThemeMode, value); + } + private ElementTheme _appThemeMode = ElementTheme.Default; [MemoryPackOrder(3)] - public GameLanguage GameLanguage { get; set; } = GameLanguage.Default; + public GameLanguage GameLanguage + { + get => _gameLanguage; + set => SetProperty(ref _gameLanguage, value); + } + private GameLanguage _gameLanguage = GameLanguage.Default; + + [MemoryPackIgnore] + public bool IsChanged { get; private set; } + [MemoryPackIgnore] + public bool IsUnchanged => !IsChanged; private const string ConfigFileName = "globalSettings.bin"; private static string ConfigFilePath => Path.Combine(App.ConfigFolder, ConfigFileName); - public void Save() + private static readonly ILogger Logger = + App.Current.Services.GetRequiredService>(); + + private GlobalSettingService() { } + + private void SetProperty(ref T field, T newValue) + { + if (EqualityComparer.Default.Equals(field, newValue)) + { + return; + } + field = newValue; + IsChanged = true; + } + + /// + /// 如果有更改,保存更改 + /// + public void SaveChanged() { + if (IsUnchanged) + { + Logger.LogInformation("配置文件未改变, 跳过写入"); + return; + } + Logger.LogInformation("配置文件保存中..."); // TODO: System.IO.Pipelines File.WriteAllBytes(ConfigFilePath, MemoryPackSerializer.Serialize(this)); + IsChanged = false; + Logger.LogInformation("配置文件保存完成"); } public static GlobalSettingService Load() @@ -39,6 +92,16 @@ public static GlobalSettingService Load() var array = new Span(new byte[reader.Length]); _ = reader.Read(array); var result = MemoryPackSerializer.Deserialize(array); - return result ?? new GlobalSettingService(); + + if (result is null) + { + result = new GlobalSettingService(); + } + else + { + result.IsChanged = false; + } + + return result; } } diff --git a/Moder.Core/Views/Menus/SettingsControlView.xaml.cs b/Moder.Core/Views/Menus/SettingsControlView.xaml.cs index 53e25dc..85282cf 100644 --- a/Moder.Core/Views/Menus/SettingsControlView.xaml.cs +++ b/Moder.Core/Views/Menus/SettingsControlView.xaml.cs @@ -1,29 +1,41 @@ -using Windows.System; using CommunityToolkit.WinUI.Controls; using Microsoft.UI.Xaml; +using Moder.Core.Services.Config; using Moder.Core.ViewsModels.Menus; +using Windows.System; namespace Moder.Core.Views.Menus; public sealed partial class SettingsControlView { - public SettingsControlViewModel ViewModel => (SettingsControlViewModel)DataContext; - public SettingsControlView(SettingsControlViewModel settingsViewModel) - { - InitializeComponent(); + private readonly GlobalSettingService _globalSettingService; + public SettingsControlViewModel ViewModel => (SettingsControlViewModel)DataContext; + + public SettingsControlView(SettingsControlViewModel settingsViewModel, GlobalSettingService globalSettingService) + { + _globalSettingService = globalSettingService; + InitializeComponent(); + + DataContext = settingsViewModel; + } - DataContext = settingsViewModel; - } + private async void OnRootPathCardClicked(object sender, RoutedEventArgs e) + { + var card = (SettingsCard)sender; + await Launcher.LaunchFolderPathAsync(card.Description.ToString()); + } - private async void OnRootPathCardClicked(object sender, RoutedEventArgs e) - { - var card = (SettingsCard)sender; - await Launcher.LaunchFolderPathAsync(card.Description.ToString()); - } + private async void OnGitHubUrlCardClicked(object sender, RoutedEventArgs e) + { + var card = (SettingsCard)sender; + await Launcher.LaunchUriAsync(new Uri(card.Description.ToString() ?? throw new InvalidOperationException())); + } - private async void OnGitHubUrlCardClicked(object sender, RoutedEventArgs e) - { - var card = (SettingsCard)sender; - await Launcher.LaunchUriAsync(new Uri(card.Description.ToString() ?? throw new InvalidOperationException())); - } -} \ No newline at end of file + /// + /// 如果有更改,保存更改 + /// + public void SaveChanged() + { + _globalSettingService.SaveChanged(); + } +}