VPet.Solution 保存初始化

This commit is contained in:
Hakoyu 2024-01-09 23:22:25 +08:00
parent 204af1d109
commit 2993c5d5eb
13 changed files with 229 additions and 25 deletions

View File

@ -10,6 +10,6 @@
<c:BoolToVisibilityConverter x:Key="FalseToHiddenConverter" />
<c:EqualsConverter x:Key="EqualsConverter" />
<c:EqualsConverter x:Key="NotEqualsConverter" Inverter="True" />
<c:ValueToBoolConverter x:Key="NullToFalse" />
<c:ValueToBoolConverter x:Key="NullToFalse" Invert="True" />
<c:BoolInverter x:Key="BoolInverter" />
</ResourceDictionary>

View File

@ -14,7 +14,7 @@ public class BoolToVisibilityConverter : BoolToValueConverterBase<BoolToVisibili
DependencyProperty.Register(
nameof(TrueVisibilityValue),
typeof(Visibility),
typeof(AllIsBoolToVisibilityConverter),
typeof(BoolToVisibilityConverter),
new PropertyMetadata(Visibility.Visible)
);
@ -35,7 +35,7 @@ public class BoolToVisibilityConverter : BoolToValueConverterBase<BoolToVisibili
DependencyProperty.Register(
nameof(FalseVisibilityValue),
typeof(Visibility),
typeof(AllIsBoolToVisibilityConverter),
typeof(BoolToVisibilityConverter),
new PropertyMetadata(Visibility.Hidden)
);

View File

@ -1,15 +1,77 @@
using HKW.WPF.Converters;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace HKW.WPF.Converters;
public class ValueToBoolConverter : ValueConverterBase
{
/// <summary>
///
/// </summary>
public static readonly DependencyProperty TargetValueProperty = DependencyProperty.Register(
nameof(TargetValue),
typeof(object),
typeof(ValueToBoolConverter),
new PropertyMetadata(null)
);
/// <summary>
/// 目标值
/// </summary>
[DefaultValue(true)]
public object TargetValue
{
get => (object)GetValue(TargetValueProperty);
set => SetValue(TargetValueProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty InvertProperty = DependencyProperty.Register(
nameof(Invert),
typeof(bool),
typeof(ValueToBoolConverter),
new PropertyMetadata(false)
);
/// <summary>
/// 颠倒
/// </summary>
[DefaultValue(false)]
public bool Invert
{
get => (bool)GetValue(InvertProperty);
set => SetValue(InvertProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty NullValueProperty = DependencyProperty.Register(
nameof(NullValue),
typeof(bool),
typeof(ValueToBoolConverter),
new PropertyMetadata(false)
);
/// <summary>
/// 为空值时布尔值
/// </summary>
[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;
}
}

View File

@ -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<SettingModel>
private string _filePath;
/// <summary>
/// 路径
/// 文件路径
/// </summary>
public string FilePath
{
@ -54,15 +55,21 @@ public class SettingModel : ObservableClass<SettingModel>
set => SetProperty(ref _interactiveSetting, value);
}
private static HashSet<string> _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<SettingModel>
}
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;
}
}
}
}

View File

@ -8,7 +8,7 @@ namespace HKW.HKWUtils.Observable;
/// 具有参数的可观察命令
/// </summary>
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {IsCanExecute.Value}\\}")]
public class ObservableCommand<T> : ObservableClass<ObservableCommand>, ICommand
public class ObservableCommand<T> : ObservableClass<ObservableCommand<T>>, ICommand
{
bool _isCanExecute = true;

View File

@ -325,6 +325,11 @@ public static class Extensions
private static Dictionary<Window, WindowCloseState> _windowCloseStates = new();
/// <summary>
/// 设置关闭状态
/// </summary>
/// <param name="window"></param>
/// <param name="state">关闭状态</param>
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)
/// <summary>
/// 强制关闭
/// </summary>
/// <param name="window"></param>
public static void CloseX(this Window? window)
{
if (window is null)
return;
_windowCloseStates.Remove(window);
window.Closing -= WindowCloseState_Closing;
window.Close();
}
/// <summary>
/// 显示或者聚焦
/// </summary>
/// <param name="window"></param>
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)

View File

@ -46,6 +46,11 @@ public class ObservablePoint : ObservableClass<ObservablePoint>, IEquatable<Obse
return new(X, Y);
}
public Point ToPoint()
{
return new Point(X, Y);
}
#region Other
/// <inheritdoc/>

View File

@ -25,7 +25,10 @@ public class GraphicsSettingPageVM : ObservableClass<GraphicsSettingPageVM>
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;
}

View File

@ -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<SettingWindowVM>
{
public static SettingWindowVM Current { get; private set; }
#region Properties
private SettingModel _currentSettings;
public SettingModel CurrentSetting
{
@ -40,6 +44,13 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
set => SetProperty(ref _searchSetting, value);
}
#endregion
#region Command
public ObservableCommand ResetSettingCommand { get; } = new();
public ObservableCommand<SettingModel> SaveSettingCommand { get; } = new();
public ObservableCommand SaveAllSettingCommand { get; } = new();
#endregion
public SettingWindowVM()
{
Current = this;
@ -49,18 +60,49 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
_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);
}
}

View File

@ -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();
}
}

View File

@ -274,7 +274,8 @@
Style="{DynamicResource Switch_BaseStyle}"
ToolTip="{ll:Str '从Steam启动该游戏, 统计时长不能停'}" />
</Grid>
<Grid MinHeight="40">
<!-- 无需设置 -->
<!--<Grid MinHeight="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
@ -302,7 +303,7 @@
Text="{ll:Str '动画描述...'}"
TextWrapping="WrapWithOverflow" />
</Grid>
</Grid>
</Grid>-->
<Grid MinHeight="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />

View File

@ -26,6 +26,8 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Style="{DynamicResource StandardTextBoxStyle}" Text="{Binding SearchSetting, UpdateSourceTrigger=PropertyChanged}" />
<ListBox
@ -37,18 +39,44 @@
Style="{DynamicResource SideMenuListBoxStyle}">
<ListBox.ItemContainerStyle>
<Style BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="ListBoxItem">
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}" />
<Setter Property="Content" Value="{Binding Name}" />
<Setter Property="ToolTip" Value="{Binding Path}" />
<Setter Property="ToolTip" Value="{Binding FilePath}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem
Command="{Binding PlacementTarget.Tag.SaveSettingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Header="{ll:Str 保存}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button
Grid.Row="2"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ResetSettingCommand}"
Content="{ll:Str 重置选中的设置}"
IsEnabled="{Binding SelectedItem, ElementName=ListBox_Saves, Converter={StaticResource NullToFalse}}"
Style="{DynamicResource Button_BaseStyle}" />
<Button
Grid.Row="3"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding SaveAllSettingCommand}"
Content="{ll:Str 全部保存}"
Style="{DynamicResource Button_BaseStyle}" />
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ListBox x:Name="ListBox_Main" Style="{DynamicResource SideMenuListBoxStyle}">
<ListBox x:Name="ListBox_Pages" Style="{DynamicResource SideMenuListBoxStyle}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
@ -64,7 +92,7 @@
<Frame
x:Name="Frame_Main"
Grid.Row="1"
Content="{Binding SelectedItem.Tag, ElementName=ListBox_Main}"
Content="{Binding SelectedItem.Tag, ElementName=ListBox_Pages}"
ContentRendered="Frame_Main_ContentRendered"
NavigationUIVisibility="Hidden" />
<!--<TabControl

View File

@ -12,6 +12,7 @@ namespace VPet.Solution.Views.SettingEditor;
/// </summary>
public partial class SettingWindow : WindowX
{
public static SettingWindow Instance { get; private set; }
public SettingWindowVM ViewModel => (SettingWindowVM)DataContext;
public SettingWindow()
@ -26,6 +27,8 @@ public partial class SettingWindow : WindowX
ListBoxItem_CustomizedSettings.Tag = new CustomizedSettingPage();
ListBoxItem_DiagnosticSettings.Tag = new DiagnosticSettingPage();
ListBoxItem_ModSettings.Tag = new ModSettingPage();
ListBox_Pages.SelectedIndex = 0;
Instance = this;
}
private void Frame_Main_ContentRendered(object sender, EventArgs e)