diff --git a/VPet.Solution/Converters.xaml b/VPet.Solution/Converters.xaml index 33e24a6..dae08b0 100644 --- a/VPet.Solution/Converters.xaml +++ b/VPet.Solution/Converters.xaml @@ -10,6 +10,6 @@ - + \ No newline at end of file diff --git a/VPet.Solution/Converters/BoolToVisibilityConverter.cs b/VPet.Solution/Converters/BoolToVisibilityConverter.cs index 9c59821..a24c4c9 100644 --- a/VPet.Solution/Converters/BoolToVisibilityConverter.cs +++ b/VPet.Solution/Converters/BoolToVisibilityConverter.cs @@ -14,7 +14,7 @@ public class BoolToVisibilityConverter : BoolToValueConverterBase + /// + /// + public static readonly DependencyProperty TargetValueProperty = DependencyProperty.Register( + nameof(TargetValue), + typeof(object), + typeof(ValueToBoolConverter), + new PropertyMetadata(null) + ); + + /// + /// 目标值 + /// + [DefaultValue(true)] + public object TargetValue + { + get => (object)GetValue(TargetValueProperty); + set => SetValue(TargetValueProperty, value); + } + + /// + /// + /// + public static readonly DependencyProperty InvertProperty = DependencyProperty.Register( + nameof(Invert), + typeof(bool), + typeof(ValueToBoolConverter), + new PropertyMetadata(false) + ); + + /// + /// 颠倒 + /// + [DefaultValue(false)] + public bool Invert + { + get => (bool)GetValue(InvertProperty); + set => SetValue(InvertProperty, value); + } + + /// + /// + /// + public static readonly DependencyProperty NullValueProperty = DependencyProperty.Register( + nameof(NullValue), + typeof(bool), + typeof(ValueToBoolConverter), + new PropertyMetadata(false) + ); + + /// + /// 为空值时布尔值 + /// + [DefaultValue(false)] + public bool NullValue + { + get => (bool)GetValue(NullValueProperty); + set => SetValue(NullValueProperty, value); + } + public override object Convert( object value, Type targetType, @@ -17,6 +79,8 @@ public class ValueToBoolConverter : ValueConverterBase CultureInfo culture ) { - throw new NotImplementedException(); + if (value is null) + return NullValue; + return value.Equals(TargetValue) ^ Invert; } } diff --git a/VPet.Solution/Models/SettingEditor/SettingModel.cs b/VPet.Solution/Models/SettingEditor/SettingModel.cs index 9ee6e71..77d85e5 100644 --- a/VPet.Solution/Models/SettingEditor/SettingModel.cs +++ b/VPet.Solution/Models/SettingEditor/SettingModel.cs @@ -1,5 +1,6 @@ using FastMember; using HKW.HKWUtils.Observable; +using LinePutScript; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; @@ -24,7 +25,7 @@ public class SettingModel : ObservableClass private string _filePath; /// - /// 路径 + /// 文件路径 /// public string FilePath { @@ -54,15 +55,21 @@ public class SettingModel : ObservableClass set => SetProperty(ref _interactiveSetting, value); } + private static HashSet _settingProperties = + new(typeof(Setting).GetProperties().Select(p => p.Name)); + + private Setting _setting; + public SettingModel(Setting setting) { - GraphicsSetting = LoadGraphicsSettings(setting); + _setting = setting; + GraphicsSetting = LoadGraphicsSettings(); } - private GraphicsSettingModel LoadGraphicsSettings(Setting setting) + private GraphicsSettingModel LoadGraphicsSettings() { var graphicsSettings = new GraphicsSettingModel(); - var sourceAccessor = ObjectAccessor.Create(setting); + var sourceAccessor = ObjectAccessor.Create(_setting); var targetAccessor = ObjectAccessor.Create(graphicsSettings); foreach (var property in typeof(GraphicsSettingModel).GetProperties()) { @@ -77,4 +84,33 @@ public class SettingModel : ObservableClass } return graphicsSettings; } + + public void Save() + { + SaveGraphicsSettings(); + File.WriteAllText(FilePath, _setting.ToString()); + } + + private void SaveGraphicsSettings() + { + var sourceAccessor = ObjectAccessor.Create(GraphicsSetting); + var targetAccessor = ObjectAccessor.Create(_setting); + foreach (var property in typeof(GraphicsSettingModel).GetProperties()) + { + //if (_settingProperties.Contains(property.Name) is false) + // continue; + var sourceValue = sourceAccessor[property.Name]; + var targetValue = targetAccessor[property.Name]; + if (sourceValue.Equals(targetValue)) + continue; + if (sourceValue is ObservablePoint point) + { + targetAccessor[property.Name] = point.ToPoint(); + } + else + { + targetAccessor[property.Name] = sourceValue; + } + } + } } diff --git a/VPet.Solution/SimpleObservable/ObservableCommand/ObservableCommandT.cs b/VPet.Solution/SimpleObservable/ObservableCommand/ObservableCommandT.cs index 0c63112..abddffe 100644 --- a/VPet.Solution/SimpleObservable/ObservableCommand/ObservableCommandT.cs +++ b/VPet.Solution/SimpleObservable/ObservableCommand/ObservableCommandT.cs @@ -8,7 +8,7 @@ namespace HKW.HKWUtils.Observable; /// 具有参数的可观察命令 /// [DebuggerDisplay("\\{ObservableCommand, CanExecute = {IsCanExecute.Value}\\}")] -public class ObservableCommand : ObservableClass, ICommand +public class ObservableCommand : ObservableClass>, ICommand { bool _isCanExecute = true; diff --git a/VPet.Solution/Utils/Expansions.cs b/VPet.Solution/Utils/Expansions.cs index 15e09ed..fbe15d4 100644 --- a/VPet.Solution/Utils/Expansions.cs +++ b/VPet.Solution/Utils/Expansions.cs @@ -325,6 +325,11 @@ public static class Extensions private static Dictionary _windowCloseStates = new(); + /// + /// 设置关闭状态 + /// + /// + /// 关闭状态 public static void SetCloseState(this Window window, WindowCloseState state) { window.Closing -= WindowCloseState_Closing; @@ -332,13 +337,32 @@ public static class Extensions _windowCloseStates[window] = state; } - public static void CloseX(this Window window) + /// + /// 强制关闭 + /// + /// + public static void CloseX(this Window? window) { + if (window is null) + return; _windowCloseStates.Remove(window); window.Closing -= WindowCloseState_Closing; window.Close(); } + /// + /// 显示或者聚焦 + /// + /// + public static void ShowOrActivate(this Window? window) + { + if (window is null) + return; + if (window.IsVisible is false) + window.Show(); + window.Activate(); + } + private static void WindowCloseState_Closing(object sender, CancelEventArgs e) { if (sender is not Window window) diff --git a/VPet.Solution/Utils/ObservablePoint.cs b/VPet.Solution/Utils/ObservablePoint.cs index 9b2ab93..f1ed5d2 100644 --- a/VPet.Solution/Utils/ObservablePoint.cs +++ b/VPet.Solution/Utils/ObservablePoint.cs @@ -46,6 +46,11 @@ public class ObservablePoint : ObservableClass, IEquatable diff --git a/VPet.Solution/ViewModels/SettingEditor/GraphicsSettingPageVM.cs b/VPet.Solution/ViewModels/SettingEditor/GraphicsSettingPageVM.cs index a1d4f49..3c1e95c 100644 --- a/VPet.Solution/ViewModels/SettingEditor/GraphicsSettingPageVM.cs +++ b/VPet.Solution/ViewModels/SettingEditor/GraphicsSettingPageVM.cs @@ -25,7 +25,10 @@ public class GraphicsSettingPageVM : ObservableClass private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e) { - if (e.PropertyName == nameof(SettingWindowVM.CurrentSetting)) + if ( + e.PropertyName == nameof(SettingWindowVM.CurrentSetting) + && sender.CurrentSetting is not null + ) { GraphicsSetting = sender.CurrentSetting.GraphicsSetting; } diff --git a/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs b/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs index 6b8c8ea..3b35d92 100644 --- a/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs +++ b/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs @@ -1,5 +1,6 @@ using HKW.HKWUtils.Observable; using LinePutScript; +using Panuon.WPF.UI; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -7,8 +8,10 @@ using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; using VPet.Solution.Models; using VPet.Solution.Models.SettingEditor; +using VPet.Solution.Views.SettingEditor; using VPet_Simulator.Windows.Interface; namespace VPet.Solution.ViewModels.SettingEditor; @@ -17,6 +20,7 @@ public class SettingWindowVM : ObservableClass { public static SettingWindowVM Current { get; private set; } + #region Properties private SettingModel _currentSettings; public SettingModel CurrentSetting { @@ -40,6 +44,13 @@ public class SettingWindowVM : ObservableClass set => SetProperty(ref _searchSetting, value); } + #endregion + + #region Command + public ObservableCommand ResetSettingCommand { get; } = new(); + public ObservableCommand SaveSettingCommand { get; } = new(); + public ObservableCommand SaveAllSettingCommand { get; } = new(); + #endregion public SettingWindowVM() { Current = this; @@ -49,18 +60,49 @@ public class SettingWindowVM : ObservableClass _settings.Add(s); PropertyChanged += MainWindowVM_PropertyChanged; + ResetSettingCommand.ExecuteCommand += ResetSettingCommand_ExecuteCommand; + SaveSettingCommand.ExecuteCommand += SaveSettingCommand_ExecuteCommand; + } + + private void SaveSettingCommand_ExecuteCommand(SettingModel parameter) + { + parameter.Save(); + } + + private void ResetSettingCommand_ExecuteCommand() + { + if ( + MessageBoxX.Show( + SettingWindow.Instance, + "确定重置吗", + "", + MessageBoxButton.YesNo, + MessageBoxIcon.Warning + ) + is not MessageBoxResult.Yes + ) + return; + CurrentSetting = _settings[_settings.IndexOf(CurrentSetting)] = new SettingModel( + new Setting("") + ); + RefreshShowSettings(SearchSetting); + } + + public void RefreshShowSettings(string name) + { + if (string.IsNullOrWhiteSpace(name)) + ShowSettings = _settings; + else + ShowSettings = _settings.Where( + s => s.Name.Contains(SearchSetting, StringComparison.OrdinalIgnoreCase) + ); } private void MainWindowVM_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(SearchSetting)) { - if (string.IsNullOrWhiteSpace(SearchSetting)) - ShowSettings = _settings; - else - ShowSettings = _settings.Where( - s => s.Name.Contains(SearchSetting, StringComparison.OrdinalIgnoreCase) - ); + RefreshShowSettings(SearchSetting); } } diff --git a/VPet.Solution/Views/MainWindow.xaml.cs b/VPet.Solution/Views/MainWindow.xaml.cs index d5765a3..070664b 100644 --- a/VPet.Solution/Views/MainWindow.xaml.cs +++ b/VPet.Solution/Views/MainWindow.xaml.cs @@ -37,8 +37,6 @@ public partial class MainWindow : WindowX private void Button_OpenSettingEditor_Click(object sender, RoutedEventArgs e) { - if (SettingWindow.IsVisible is false) - SettingWindow.Show(); - SettingWindow.Activate(); + SettingWindow.ShowOrActivate(); } } diff --git a/VPet.Solution/Views/SettingEditor/GraphicsSettingPage.xaml b/VPet.Solution/Views/SettingEditor/GraphicsSettingPage.xaml index bf53996..250a6fb 100644 --- a/VPet.Solution/Views/SettingEditor/GraphicsSettingPage.xaml +++ b/VPet.Solution/Views/SettingEditor/GraphicsSettingPage.xaml @@ -274,7 +274,8 @@ Style="{DynamicResource Switch_BaseStyle}" ToolTip="{ll:Str '从Steam启动该游戏, 统计时长不能停'}" /> - + + diff --git a/VPet.Solution/Views/SettingEditor/SettingWindow.xaml b/VPet.Solution/Views/SettingEditor/SettingWindow.xaml index dabea02..989afa4 100644 --- a/VPet.Solution/Views/SettingEditor/SettingWindow.xaml +++ b/VPet.Solution/Views/SettingEditor/SettingWindow.xaml @@ -26,6 +26,8 @@ + + +