VPet.Solution 实装 CustomizedSetting DiagnosticSetting ModSetting

This commit is contained in:
Hakoyu 2024-01-16 04:46:14 +08:00
parent 262b3b4230
commit 7528763fd9
21 changed files with 1327 additions and 392 deletions

View File

@ -8,6 +8,16 @@
<c:StringFormatConverter x:Key="StringFormatConverter" />
<c:BrushToMediaColorConverter x:Key="BrushToMediaColorConverter" />
<c:BoolToVisibilityConverter x:Key="FalseToHiddenConverter" />
<c:BoolToVisibilityConverter
x:Key="FalseToVisibleConverter"
FalseVisibilityValue="Visible"
NullValue="True"
TrueVisibilityValue="Hidden" />
<c:NullToVisibilityConverter x:Key="NotNullToVisibleConverter" />
<c:NullToVisibilityConverter
x:Key="NullToVisibleConverter"
NotNullVisibilityValue="Hidden"
NullVisibilityValue="Visible" />
<c:EqualsConverter x:Key="EqualsConverter" />
<c:EqualsConverter x:Key="NotEqualsConverter" Inverter="True" />
<c:ValueToBoolConverter x:Key="NullToFalse" Invert="True" />

View File

@ -13,7 +13,7 @@ public class BoolInverter : ValueConverterBase
public static readonly DependencyProperty NullValueProperty = DependencyProperty.Register(
nameof(NullValue),
typeof(bool),
typeof(AllIsBoolToVisibilityConverter),
typeof(BoolInverter),
new PropertyMetadata(false)
);

View File

@ -0,0 +1,60 @@
using System.ComponentModel;
using System.Globalization;
using System.Windows;
namespace HKW.WPF.Converters;
public class NullToVisibilityConverter : ValueConverterBase
{
/// <summary>
///
/// </summary>
public static readonly DependencyProperty NullVisibilityValueProperty =
DependencyProperty.Register(
nameof(NullVisibilityValue),
typeof(Visibility),
typeof(NullToVisibilityConverter),
new PropertyMetadata(Visibility.Hidden)
);
/// <summary>
/// NULL时的可见度
/// </summary>
[DefaultValue(Visibility.Hidden)]
public Visibility NullVisibilityValue
{
get => (Visibility)GetValue(NullVisibilityValueProperty);
set => SetValue(NullVisibilityValueProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty NotNullVisibilityValueProperty =
DependencyProperty.Register(
nameof(NotNullVisibilityValue),
typeof(Visibility),
typeof(NullToVisibilityConverter),
new PropertyMetadata(Visibility.Visible)
);
/// <summary>
/// 不为NULL时的可见度
/// </summary>
[DefaultValue(Visibility.Visible)]
public Visibility NotNullVisibilityValue
{
get => (Visibility)GetValue(NotNullVisibilityValueProperty);
set => SetValue(NotNullVisibilityValueProperty, value);
}
public override object Convert(
object value,
Type targetType,
object parameter,
CultureInfo culture
)
{
return value is null ? NullVisibilityValue : NotNullVisibilityValue;
}
}

View File

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LinePutScript;
using LinePutScript.Converter;
using LinePutScript.Dictionary;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using VPet_Simulator.Core;
using VPet_Simulator.Windows.Interface;
using System.Windows.Media.Imaging;
namespace VPet.Solution.Models;
/// <summary>
/// 模组加载器
/// </summary>
public class ModLoader
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; }
/// <summary>
/// 如果是上传至Steam,则为SteamUserID
/// </summary>
public long AuthorID { get; }
/// <summary>
/// 上传至Steam的ItemID
/// </summary>
public ulong ItemID { get; }
/// <summary>
/// 简介
/// </summary>
public string Intro { get; }
/// <summary>
/// 模组路径
/// </summary>
public string ModPath { get; }
/// <summary>
/// 支持的游戏版本
/// </summary>
public int GameVer { get; }
/// <summary>
/// 版本
/// </summary>
public int Ver { get; }
/// <summary>
/// 标签
/// </summary>
public HashSet<string> Tags { get; } = new();
/// <summary>
/// 缓存数据
/// </summary>
public DateTime CacheDate { get; } = DateTime.MinValue;
public BitmapImage? Image { get; } = null;
public ModLoader(string path)
{
ModPath = path;
var modlps = new LpsDocument(File.ReadAllText(Path.Combine(path + @"\info.lps")));
Name = modlps.FindLine("vupmod").Info;
Intro = modlps.FindLine("intro").Info;
GameVer = modlps.FindSub("gamever").InfoToInt;
Ver = modlps.FindSub("ver").InfoToInt;
Author = modlps.FindSub("author").Info.Split('[').First();
if (modlps.FindLine("authorid") != null)
AuthorID = modlps.FindLine("authorid").InfoToInt64;
else
AuthorID = 0;
if (modlps.FindLine("itemid") != null)
ItemID = Convert.ToUInt64(modlps.FindLine("itemid").info);
else
ItemID = 0;
CacheDate = modlps.GetDateTime("cachedate", DateTime.MinValue);
var imagePath = Path.Combine(path, "icon.png");
if (File.Exists(imagePath))
{
try
{
Image = Utils.LoadImageToStream(imagePath);
}
catch { }
}
foreach (var dir in Directory.EnumerateDirectories(path))
{
switch (dir.ToLower())
{
case "pet":
//宠物模型
Tags.Add("pet");
break;
case "food":
Tags.Add("food");
break;
case "image":
Tags.Add("image");
break;
case "text":
Tags.Add("text");
break;
case "lang":
Tags.Add("lang");
break;
}
}
}
}

View File

@ -0,0 +1,55 @@
using System.Collections.ObjectModel;
namespace VPet.Solution.Models.SettingEditor;
public class CustomizedSettingModel : ObservableClass<CustomizedSettingModel>
{
public const string TargetName = "diy";
#region Links
private ObservableCollection<LinkModel> _links = new();
public ObservableCollection<LinkModel> Links
{
get => _links;
set => SetProperty(ref _links, value);
}
#endregion
}
public class LinkModel : ObservableClass<LinkModel>
{
#region Name
private string _name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
#endregion
#region Link
private string _link;
/// <summary>
/// 链接
/// </summary>
public string Link
{
get => _link;
set => SetProperty(ref _link, value);
}
#endregion
public LinkModel() { }
public LinkModel(string name, string link)
{
Name = name;
Link = link;
}
}

View File

@ -0,0 +1,68 @@
using HKW.HKWUtils.Observable;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VPet_Simulator.Windows.Interface;
namespace VPet.Solution.Models.SettingEditor;
public class DiagnosticSettingModel : ObservableClass<DiagnosticSettingModel>
{
#region AutoCal
private bool _autoCal;
/// <summary>
/// 自动修复超模
/// </summary>
public bool AutoCal
{
get => _autoCal;
set => SetProperty(ref _autoCal, value);
}
#endregion
#region Diagnosis
private bool _diagnosis;
/// <summary>
/// 是否启用数据收集
/// </summary>
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.Diagnosis))]
public bool Diagnosis
{
get => _diagnosis;
set => SetProperty(ref _diagnosis, value);
}
#endregion
#region DiagnosisInterval
private int _diagnosisInterval = 200;
/// <summary>
/// 数据收集频率
/// </summary>
[DefaultValue(200)]
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.DiagnosisInterval))]
public int DiagnosisInterval
{
get => _diagnosisInterval;
set => SetProperty(ref _diagnosisInterval, value);
}
public static ObservableCollection<int> DiagnosisIntervals { get; } =
new() { 200, 500, 1000, 2000, 5000, 10000, 20000 };
#endregion
public void GetAutoCalFromSetting(Setting setting)
{
AutoCal = setting["gameconfig"].GetBool("noAutoCal") is false;
}
public void SetAutoCalToSetting(Setting setting)
{
setting["gameconfig"].SetBool("noAutoCal", AutoCal is false);
}
}

View File

@ -0,0 +1,287 @@
using HKW.HKWUtils.Observable;
using LinePutScript;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using VPet_Simulator.Windows.Interface;
namespace VPet.Solution.Models.SettingEditor;
public class ModSettingModel : ObservableClass<ModSettingModel>
{
public const string ModLineName = "onmod";
public const string PassModLineName = "passmod";
public const string MsgModLineName = "msgmod";
public static string ModDirectory = Path.Combine(Environment.CurrentDirectory, "mod");
public static Dictionary<string, ModLoader> LocalMods = Directory.Exists(ModDirectory) is false
? new(StringComparer.OrdinalIgnoreCase)
: new(
Directory
.EnumerateDirectories(ModDirectory)
.Select(d => new ModLoader(d))
.ToDictionary(m => m.Name, m => m),
StringComparer.OrdinalIgnoreCase
);
#region Mods
private ObservableCollection<ModModel> _mods = new();
public ObservableCollection<ModModel> Mods
{
get => _mods;
set => SetProperty(ref _mods, value);
}
public ModSettingModel(Setting setting)
{
foreach (var item in setting[ModLineName])
{
var modName = item.Name;
if (LocalMods.TryGetValue(modName, out var loader))
{
var modModel = new ModModel(loader);
modModel.IsPass = setting[PassModLineName].Contains(modName);
modModel.IsMsg = setting[MsgModLineName].Contains(modModel.Name);
Mods.Add(modModel);
}
else
Mods.Add(new());
}
}
public void Close()
{
foreach (var modLoader in LocalMods)
{
modLoader.Value.Image.CloseStream();
}
}
public void Save(Setting setting)
{
setting.Remove(ModLineName);
setting.Remove(PassModLineName);
setting.Remove(MsgModLineName);
if (Mods.Any() is false)
return;
foreach (var mod in Mods)
{
setting[ModLineName].Add(new Sub(mod.Name.ToLower()));
setting[MsgModLineName].Add(new Sub(mod.Name, "True"));
if (mod.IsPass)
setting[PassModLineName].Add(new Sub(mod.Name.ToLower()));
}
}
#endregion
}
public class ModModel : ObservableClass<ModModel>
{
#region Name
private string _name;
/// <summary>
/// 名称
/// </summary>
[ReflectionProperty(nameof(ModLoader.Name))]
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
#endregion
#region Description
private string _description;
/// <summary>
/// 描述
/// </summary>
[ReflectionProperty(nameof(ModLoader.Intro))]
public string Description
{
get => _description;
set => SetProperty(ref _description, value);
}
#endregion
#region Author
private string _author;
/// <summary>
/// 作者
/// </summary>
[ReflectionProperty(nameof(ModLoader.Author))]
public string Author
{
get => _author;
set => SetProperty(ref _author, value);
}
#endregion
#region ModVersion
private int _modVersion;
/// <summary>
/// 模组版本
/// </summary>
[ReflectionProperty(nameof(ModLoader.Ver))]
public int ModVersion
{
get => _modVersion;
set => SetProperty(ref _modVersion, value);
}
#endregion
#region GameVersion
private int _gameVersion;
/// <summary>
/// 游戏版本
/// </summary>
[ReflectionProperty(nameof(ModLoader.GameVer))]
public int GameVersion
{
get => _gameVersion;
set => SetProperty(ref _gameVersion, value);
}
#endregion
#region Tags
private HashSet<string> _tags;
/// <summary>
/// 功能
/// </summary>
[ReflectionProperty(nameof(ModLoader.Tags))]
public HashSet<string> Tags
{
get => _tags;
set => SetProperty(ref _tags, value);
}
#endregion
#region Image
private BitmapImage _image;
/// <summary>
/// 图像
/// </summary>
[ReflectionProperty(nameof(ModLoader.Image))]
public BitmapImage Image
{
get => _image;
set => SetProperty(ref _image, value);
}
#endregion
#region ItemId
private ulong _itemId;
[ReflectionProperty(nameof(ModLoader.ItemID))]
public ulong ItemId
{
get => _itemId;
set => SetProperty(ref _itemId, value);
}
#endregion
#region ModPath
private string _modPath;
[ReflectionProperty(nameof(ModLoader.ModPath))]
public string ModPath
{
get => _modPath;
set => SetProperty(ref _modPath, value);
}
#endregion
#region IsEnabled
private bool? _isEnabled = true;
/// <summary>
/// 已启用
/// </summary>
public bool? IsEnabled
{
get => _isEnabled;
set => SetProperty(ref _isEnabled, value);
}
#endregion
#region IsPass
private bool _isPass;
/// <summary>
/// 是通过检查的代码模组
/// </summary>
public bool IsPass
{
get => _isPass;
set => SetProperty(ref _isPass, value);
}
#endregion
#region IsMsg
private bool _isMsg;
/// <summary>
/// 是含有代码的模组
/// </summary>
public bool IsMsg
{
get => _isMsg;
set => SetProperty(ref _isMsg, value);
}
#endregion
#region State
private string _state;
public string State
{
get => _state;
set => SetProperty(ref _state, value);
}
#endregion
public ModModel()
{
PropertyChanged += ModModel_PropertyChanged;
IsEnabled = null;
}
private void ModModel_PropertyChanged(
object sender,
System.ComponentModel.PropertyChangedEventArgs e
)
{
if (e.PropertyName == nameof(IsEnabled))
{
RefreshState();
}
}
public ModModel(ModLoader loader)
{
PropertyChanged += ModModel_PropertyChanged;
ReflectionUtils.SetValue(loader, this);
RefreshState();
}
public void RefreshState()
{
if (IsEnabled is true)
State = "已启用";
else if (IsEnabled is false)
State = "已关闭";
else
State = "已损坏";
}
}

View File

@ -50,12 +50,37 @@ public class SettingModel : ObservableClass<SettingModel>
}
#endregion
private static HashSet<string> _settingProperties =
new(typeof(Setting).GetProperties().Select(p => p.Name));
#region CustomizedSetting
private CustomizedSettingModel _CustomizedSetting;
public CustomizedSettingModel CustomizedSetting
{
get => _CustomizedSetting;
set => SetProperty(ref _CustomizedSetting, value);
}
#endregion
private Setting _setting;
#region DiagnosticSetting
private DiagnosticSettingModel _diagnosticSetting;
public DiagnosticSettingModel DiagnosticSetting
{
get => _diagnosticSetting;
set => SetProperty(ref _diagnosticSetting, value);
}
#endregion
private ReflectionOptions _saveReflectionOptions = new() { CheckValueEquals = true };
#region ModSetting
private ModSettingModel _modSetting;
public ModSettingModel ModSetting
{
get => _modSetting;
set => SetProperty(ref _modSetting, value);
}
#endregion
private readonly Setting _setting;
private readonly ReflectionOptions _saveReflectionOptions = new() { CheckValueEquals = true };
public SettingModel()
: this(new("")) { }
@ -66,14 +91,39 @@ public class SettingModel : ObservableClass<SettingModel>
GraphicsSetting = LoadSetting<GraphicsSettingModel>();
InteractiveSetting = LoadSetting<InteractiveSettingModel>();
SystemSetting = LoadSetting<SystemSettingModel>();
CustomizedSetting = LoadCustomizedSetting(setting);
DiagnosticSetting = LoadSetting<DiagnosticSettingModel>();
DiagnosticSetting.SetAutoCalToSetting(setting);
ModSetting = LoadModSetting(setting);
}
private ModSettingModel LoadModSetting(Setting setting)
{
var settingModel = new ModSettingModel(setting);
return settingModel;
}
private CustomizedSettingModel LoadCustomizedSetting(Setting setting)
{
var model = new CustomizedSettingModel();
if (setting[CustomizedSettingModel.TargetName] is ILine line && line.Count > 0)
{
foreach (var sub in line)
model.Links.Add(new(sub.Name, sub.Info));
}
else
{
setting.Remove(CustomizedSettingModel.TargetName);
}
return model;
}
private T LoadSetting<T>()
where T : new()
{
var setting = new T();
ReflectionUtils.SetValue(_setting, setting);
return setting;
var settingModel = new T();
ReflectionUtils.SetValue(_setting, settingModel);
return settingModel;
}
public void Save()
@ -81,11 +131,16 @@ public class SettingModel : ObservableClass<SettingModel>
SaveSetting(GraphicsSetting);
SaveSetting(InteractiveSetting);
SaveSetting(SystemSetting);
SaveSetting(DiagnosticSetting);
DiagnosticSetting.SetAutoCalToSetting(_setting);
foreach (var link in CustomizedSetting.Links)
_setting[CustomizedSettingModel.TargetName].Add(new Sub(link.Name, link.Link));
ModSetting.Save(_setting);
File.WriteAllText(FilePath, _setting.ToString());
}
private void SaveSetting(object setting)
private void SaveSetting(object settingModel)
{
ReflectionUtils.SetValue(setting, _setting, _saveReflectionOptions);
ReflectionUtils.SetValue(settingModel, _setting, _saveReflectionOptions);
}
}

View File

@ -9,34 +9,6 @@ public class SystemSettingModel : ObservableClass<SystemSettingModel>
/// </summary>
public bool DiagnosisDayEnable { get; } = true;
#region Diagnosis
private bool _diagnosis;
/// <summary>
/// 是否启用数据收集
/// </summary>
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.Diagnosis))]
public bool Diagnosis
{
get => _diagnosis;
set => SetProperty(ref _diagnosis, value);
}
#endregion
#region DiagnosisInterval
private int _diagnosisInterval;
/// <summary>
/// 数据收集频率
/// </summary>
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.DiagnosisInterval))]
public int DiagnosisInterval
{
get => _diagnosisInterval;
set => SetProperty(ref _diagnosisInterval, value);
}
#endregion
#region AutoSaveInterval
private int _autoSaveInterval;

View File

@ -8,5 +8,5 @@ public delegate Task ExecuteAsyncEventHandler();
/// <summary>
/// 异步执行命令事件
/// </summary>
/// <param name="parameter"></param>
/// <param name="parameter">参数</param>
public delegate Task ExecuteAsyncEventHandler<T>(T parameter);

View File

@ -18,21 +18,27 @@ public static class Utils
public const int DecodePixelHeight = 250;
public static char[] Separator { get; } = new char[] { '_' };
//public static BitmapImage LoadImageToStream(string imagePath)
//{
// BitmapImage bitmapImage = new();
// bitmapImage.BeginInit();
// bitmapImage.DecodePixelWidth = DecodePixelWidth;
// try
// {
// bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream;
// }
// finally
// {
// bitmapImage.EndInit();
// }
// return bitmapImage;
//}
/// <summary>
/// 载入图片到流
/// </summary>
/// <param name="imagePath">图片路径</param>
/// <returns>图片</returns>
public static BitmapImage LoadImageToStream(string imagePath)
{
if (string.IsNullOrWhiteSpace(imagePath) || File.Exists(imagePath) is false)
return null;
BitmapImage bitmapImage = new();
bitmapImage.BeginInit();
try
{
bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream;
}
finally
{
bitmapImage.EndInit();
}
return bitmapImage;
}
/// <summary>
/// 载入图片至内存流
@ -100,7 +106,7 @@ public static class Utils
/// 打开文件
/// </summary>
/// <param name="filePath">文件路径</param>
public static void OpenFile(string filePath)
public static void OpenLink(string filePath)
{
System.Diagnostics.Process
.Start(new System.Diagnostics.ProcessStartInfo(filePath) { UseShellExecute = true })

View File

@ -90,15 +90,20 @@
<Compile Include="Converters\IsBoolConverter.cs" />
<Compile Include="Converters\MarginConverter.cs" />
<Compile Include="Converters\MediaColorToBrushConverter.cs" />
<Compile Include="Converters\NullToVisibilityConverter.cs" />
<Compile Include="Converters\StringFormatConverter.cs" />
<Compile Include="Converters\BoolToVisibilityConverter.cs" />
<Compile Include="Converters\MaxConverter.cs" />
<Compile Include="Converters\ValueToBoolConverter.cs" />
<Compile Include="Converters\BoolInverter.cs" />
<Compile Include="Models\ModLoader.cs" />
<Compile Include="Models\SaveViewer\SaveModel.cs" />
<Compile Include="Models\SaveViewer\StatisticDataModel.cs" />
<Compile Include="Models\SettingEditor\CustomizedSettingModel.cs" />
<Compile Include="Models\SettingEditor\DiagnosticSettingModel.cs" />
<Compile Include="Models\SettingEditor\GraphicsSettingModel.cs" />
<Compile Include="Models\SettingEditor\InteractiveSettingModel.cs" />
<Compile Include="Models\SettingEditor\ModSettingModel.cs" />
<Compile Include="Models\SettingEditor\SystemSettingModel.cs" />
<Compile Include="Utils\ClearFocus.cs" />
<Compile Include="Utils\ElementHelper.cs" />
@ -110,6 +115,7 @@
<Compile Include="ViewModels\SaveViewer\SaveWindowVM.cs" />
<Compile Include="ViewModels\SettingEditor\CustomizedSettingPageVM.cs" />
<Compile Include="ViewModels\SettingEditor\DiagnosticSettingPageVM.cs" />
<Compile Include="ViewModels\SettingEditor\ModSettingModelModel.cs" />
<Compile Include="ViewModels\SettingEditor\ModSettingPageVM.cs" />
<Compile Include="Models\SettingEditor\SettingModel.cs" />
<Compile Include="ViewModels\SettingEditor\SystemSettingPageVM.cs" />

View File

@ -77,7 +77,7 @@ public class SaveWindowVM : ObservableClass<SaveWindowVM>
private void OpenFileCommand_ExecuteCommand(SaveModel parameter)
{
Utils.OpenFile(parameter.FilePath);
Utils.OpenLink(parameter.FilePath);
}
public void RefreshShowSaves(string name)

View File

@ -1,9 +1,112 @@
using System;
using HKW.HKWUtils.Observable;
using LinePutScript.Localization.WPF;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VPet.Solution.Models.SettingEditor;
namespace VPet.Solution.ViewModels.SettingEditor;
public class CustomizedSettingPageVM { }
public class CustomizedSettingPageVM : ObservableClass<CustomizedSettingPageVM>
{
#region ObservableProperty
#region CustomizedSetting
private CustomizedSettingModel _customizedSetting;
public CustomizedSettingModel CustomizedSetting
{
get => _customizedSetting;
set => SetProperty(ref _customizedSetting, value);
}
#endregion
#region SearchSetting
private string _searchSetting;
public string SearchLink
{
get => _searchSetting;
set
{
SetProperty(ref _searchSetting, value);
RefreshShowLinks(value);
}
}
#endregion
#region ShowLinks
private IEnumerable<LinkModel> _showLinks;
public IEnumerable<LinkModel> ShowLinks
{
get => _showLinks;
set => SetProperty(ref _showLinks, value);
}
#endregion
#endregion
#region Command
public ObservableCommand AddLinkCommand { get; } = new();
public ObservableCommand<LinkModel> RemoveLinkCommand { get; } = new();
public ObservableCommand ClearLinksCommand { get; } = new();
#endregion
public CustomizedSettingPageVM()
{
SettingWindowVM.Current.PropertyChangedX += Current_PropertyChangedX;
AddLinkCommand.ExecuteCommand += AddLinkCommand_ExecuteCommand;
RemoveLinkCommand.ExecuteCommand += RemoveLinkCommand_ExecuteCommand;
ClearLinksCommand.ExecuteCommand += ClearLinksCommand_ExecuteCommand;
}
private void ClearLinksCommand_ExecuteCommand()
{
if (
MessageBox.Show(
"确定清空吗".Translate(),
"",
MessageBoxButton.YesNo,
MessageBoxImage.Warning
)
is not MessageBoxResult.Yes
)
return;
SearchLink = string.Empty;
CustomizedSetting.Links.Clear();
}
private void AddLinkCommand_ExecuteCommand()
{
SearchLink = string.Empty;
CustomizedSetting.Links.Add(new());
}
private void RemoveLinkCommand_ExecuteCommand(LinkModel parameter)
{
CustomizedSetting.Links.Remove(parameter);
}
private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e)
{
if (
e.PropertyName == nameof(SettingWindowVM.CurrentSetting)
&& sender.CurrentSetting is not null
)
{
CustomizedSetting = sender.CurrentSetting.CustomizedSetting;
SearchLink = string.Empty;
}
}
public void RefreshShowLinks(string name)
{
if (string.IsNullOrWhiteSpace(name))
ShowLinks = CustomizedSetting.Links;
else
ShowLinks = CustomizedSetting.Links.Where(
s => s.Name.Contains(SearchLink, StringComparison.OrdinalIgnoreCase)
);
}
}

View File

@ -3,7 +3,32 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VPet.Solution.Models.SettingEditor;
namespace VPet.Solution.ViewModels.SettingEditor;
public class DiagnosticSettingPageVM { }
public class DiagnosticSettingPageVM : ObservableClass<DiagnosticSettingPageVM>
{
private DiagnosticSettingModel _diagnosticSetting;
public DiagnosticSettingModel DiagnosticSetting
{
get => _diagnosticSetting;
set => SetProperty(ref _diagnosticSetting, value);
}
public DiagnosticSettingPageVM()
{
SettingWindowVM.Current.PropertyChangedX += Current_PropertyChangedX;
}
private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e)
{
if (
e.PropertyName == nameof(SettingWindowVM.CurrentSetting)
&& sender.CurrentSetting is not null
)
{
DiagnosticSetting = sender.CurrentSetting.DiagnosticSetting;
}
}
}

View File

@ -0,0 +1,5 @@
namespace VPet.Solution.ViewModels.SettingEditor;
internal class ModSettingModelModel
{
}

View File

@ -1,9 +1,164 @@
using System;
using HKW.HKWUtils.Observable;
using LinePutScript.Localization.WPF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VPet.Solution.Models.SettingEditor;
namespace VPet.Solution.ViewModels.SettingEditor;
public class ModSettingPageVM { }
public class ModSettingPageVM : ObservableClass<ModSettingPageVM>
{
#region ObservableProperty
private ModSettingModel _modSetting;
public ModSettingModel ModSetting
{
get => _modSetting;
set => SetProperty(ref _modSetting, value);
}
#region ShowMods
private IEnumerable<ModModel> _showMods;
public IEnumerable<ModModel> ShowMods
{
get => _showMods;
set => SetProperty(ref _showMods, value);
}
#endregion
#region SearchMod
private string _searchMod;
public string SearchMod
{
get => _searchMod;
set
{
SetProperty(ref _searchMod, value);
RefreshShowMods(value);
}
}
#endregion
#region CurrentModMoel
private ModModel _currentModModel;
public ModModel CurrentModMoel
{
get => _currentModModel;
set
{
if (_currentModModel is not null)
_currentModModel.PropertyChangingX -= CurrentModModel_PropertyChangingX;
SetProperty(ref _currentModModel, value);
if (value is not null)
_currentModModel.PropertyChangingX += CurrentModModel_PropertyChangingX;
}
}
private void CurrentModModel_PropertyChangingX(ModModel sender, PropertyChangingXEventArgs e)
{
if (e.PropertyName == nameof(ModModel.IsPass) && e.NewValue is true)
{
if (
MessageBox.Show(
"是否启用 {0} 的代码插件?\n一经启用,该插件将会允许访问该系统(包括外部系统)的所有数据\n如果您不确定,请先使用杀毒软件查杀检查".Translate(
sender.Name
),
"启用 {0} 的代码插件?".Translate(sender.Name),
MessageBoxButton.YesNo,
MessageBoxImage.Warning
) is MessageBoxResult.Yes
)
{
sender.IsEnabled = true;
}
else
e.Cancel = true;
}
}
#endregion
#endregion
#region Command
//public ObservableCommand AddModCommand { get; } = new();
//public ObservableCommand<ModModel> RemoveModCommand { get; } = new();
public ObservableCommand ClearFailModsCommand { get; } = new();
public ObservableCommand ClearModsCommand { get; } = new();
public ObservableCommand<ModModel> OpenModPathCommand { get; } = new();
public ObservableCommand<ModModel> OpenSteamCommunityCommand { get; } = new();
#endregion
public ModSettingPageVM()
{
SettingWindowVM.Current.PropertyChangedX += Current_PropertyChangedX;
ClearFailModsCommand.ExecuteCommand += ClearFailModsCommand_ExecuteCommand;
ClearModsCommand.ExecuteCommand += ClearModsCommand_ExecuteCommand;
OpenModPathCommand.ExecuteCommand += OpenModPathCommand_ExecuteCommand;
OpenSteamCommunityCommand.ExecuteCommand += OpenSteamCommunityCommand_ExecuteCommand;
}
private void ClearModsCommand_ExecuteCommand()
{
if (
MessageBox.Show("确定清除全部模组吗", "", MessageBoxButton.YesNo, MessageBoxImage.Warning)
is not MessageBoxResult.Yes
)
return;
ModSetting.Mods.Clear();
SearchMod = string.Empty;
}
private void ClearFailModsCommand_ExecuteCommand()
{
if (
MessageBox.Show("确定清除全部失效模组吗", "", MessageBoxButton.YesNo, MessageBoxImage.Warning)
is not MessageBoxResult.Yes
)
return;
foreach (var mod in ModSetting.Mods.AsEnumerable())
{
if (mod.IsEnabled is null)
ModSetting.Mods.Remove(mod);
}
SearchMod = string.Empty;
}
private void OpenSteamCommunityCommand_ExecuteCommand(ModModel parameter)
{
Utils.OpenLink(
"https://steamcommunity.com/sharedfiles/filedetails/?id=" + parameter.ItemId
);
}
private void OpenModPathCommand_ExecuteCommand(ModModel parameter)
{
Utils.OpenLink(parameter.ModPath);
}
private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e)
{
if (
e.PropertyName == nameof(SettingWindowVM.CurrentSetting)
&& sender.CurrentSetting is not null
)
{
ModSetting = sender.CurrentSetting.ModSetting;
SearchMod = string.Empty;
}
}
public void RefreshShowMods(string name)
{
if (string.IsNullOrWhiteSpace(name))
ShowMods = ModSetting.Mods;
else
ShowMods = ModSetting.Mods.Where(
s => s.Name.Contains(SearchMod, StringComparison.OrdinalIgnoreCase)
);
}
}

View File

@ -94,7 +94,7 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
private void OpenFileCommand_ExecuteCommand(SettingModel parameter)
{
Utils.OpenFile(parameter.FilePath);
Utils.OpenLink(parameter.FilePath);
}
private void SaveAllSettingCommand_ExecuteCommand()

View File

@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:h="clr-namespace:HKW.WPF.Helpers"
xmlns:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF"
xmlns:local="clr-namespace:VPet.Solution.Views.SettingEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -15,43 +16,80 @@
mc:Ignorable="d">
<Grid>
<StackPanel>
<TextBlock Background="{x:Null}" TextWrapping="Wrap">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 自定义链接}" /><LineBreak />
<Run Text="{ll:Str '在自定栏添加快捷方式/网页/快捷键, 可以便携启动想要的功能'}" /><LineBreak />
<Run Text="{ll:Str '键盘快捷键编写方法请参考'}" /> <Hyperlink d:Click="sendkey_click">
<Run Text="{ll:Str '键盘快捷键编写方法请参考'}" /> <Hyperlink>
<Run Text="{ll:Str '键盘快捷键 通用注解'}" />
</Hyperlink><LineBreak />
<Run Text="{ll:Str '右键进行排序/删除等操作'}" />
</TextBlock>
<Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="btn_DIY"
Margin="4"
Padding="1"
d:Click="DIY_ADD_Click"
pu:ButtonHelper.CornerRadius="4"
Background="{DynamicResource SecondaryLight}"
Content="{ll:Str 添加新链接}" />
Padding="20,5,20,5"
Command="{Binding AddLinkCommand}"
Content="{ll:Str 添加新链接}"
Style="{DynamicResource Button_BaseStyle}" />
<Button
Grid.Column="1"
Margin="4"
Padding="1"
Padding="20,5,20,5"
d:Click="DIY_Save_Click"
pu:ButtonHelper.CornerRadius="4"
Background="{DynamicResource SecondaryLight}"
Content="{ll:Str 保存设置}" />
Command="{Binding ClearLinksCommand}"
Content="{ll:Str 清空全部}"
Style="{DynamicResource Button_BaseStyle}" />
</Grid>
<ScrollViewer>
<StackPanel x:Name="StackDIY" />
</ScrollViewer>
</StackPanel>
<TextBox
Grid.Row="2"
pu:TextBoxHelper.Watermark="{ll:Str 搜索名称}"
Style="{DynamicResource StandardTextBoxStyle}"
Text="{Binding SearchLink, UpdateSourceTrigger=PropertyChanged}" />
<DataGrid
Grid.Row="3"
d:ItemsSource="{d:SampleData ItemCount=10}"
AutoGenerateColumns="False"
CanUserAddRows="False"
ItemsSource="{Binding ShowLinks}"
VerticalScrollBarVisibility="Auto">
<DataGrid.RowStyle>
<Style BasedOn="{StaticResource {x:Type DataGridRow}}" TargetType="DataGridRow">
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Page}}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=Self}}">
<MenuItem
Command="{Binding PlacementTarget.Tag.RemoveLinkCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="{ll:Str 删除}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
EditingElementStyle="{DynamicResource TextBox_LeftCenter}"
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
Header="{ll:Str 名称}" />
<DataGridTextColumn
Binding="{Binding Link, UpdateSourceTrigger=PropertyChanged}"
EditingElementStyle="{DynamicResource TextBox_LeftCenter}"
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
Header="{ll:Str 链接}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Page>

View File

@ -13,8 +13,6 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<ScrollViewer>
<StackPanel>
<TextBlock
HorizontalAlignment="Left"
@ -30,22 +28,9 @@
<pu:Switch
x:Name="swAutoCal"
Grid.Column="2"
Margin="20,0,0,0"
HorizontalAlignment="Left"
d:Checked="swAutoCal_Checked"
d:Unchecked="swAutoCal_Checked"
Background="Transparent"
BorderBrush="{DynamicResource PrimaryDark}"
BoxHeight="18"
BoxWidth="35"
CheckedBackground="{DynamicResource Primary}"
CheckedBorderBrush="{DynamicResource Primary}"
CheckedToggleBrush="{DynamicResource DARKPrimaryText}"
Content="{ll:Str '自动计算合理价格'}"
ToggleBrush="{DynamicResource PrimaryDark}"
ToggleShadowColor="{x:Null}"
ToggleSize="14"
ToolTip="{ll:Str '该选项重启后生效'}" />
IsChecked="{Binding DiagnosticSetting.AutoCal}"
Style="{DynamicResource Switch_BaseStyle}" />
<TextBlock
Margin="0,20,0,0"
HorizontalAlignment="Left"
@ -67,25 +52,13 @@
FontWeight="Bold"
Text="通过" />
</TextBlock>
<RadioButton
<pu:Switch
x:Name="RBDiagnosisYES"
Margin="10,10,10,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:Checked="RBDiagnosisYES_Checked"
Content="{ll:Str '发送诊断数据: 发送游戏存档, 包括饱腹,状态等各种游戏内\&#13;数据. 可能会包括该游戏内存和CPU使用情况'}"
GroupName="diagnosis"
Style="{DynamicResource StandardRadioButtonStyle}" />
<RadioButton
x:Name="RBDiagnosisNO"
Margin="10,10,10,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:Checked="RBDiagnosisNO_Checked"
CheckedContent="{ll:Str '发送诊断数据: 发送游戏存档, 包括饱腹,状态等各种游戏内\&#13;数据. 可能会包括该游戏内存和CPU使用情况'}"
Content="{ll:Str '不发送诊断数据: 适用于启用修改器,修改过游戏数据等不\&#13;符合分析数据条件. 或不希望提供游戏数据的玩家'}"
GroupName="diagnosis"
IsChecked="True"
Style="{DynamicResource StandardRadioButtonStyle}" />
IsChecked="{Binding DiagnosticSetting.Diagnosis}"
Style="{DynamicResource Switch_BaseStyle}" />
<StackPanel>
<TextBlock
Margin="0,15,0,0"
HorizontalAlignment="Left"
@ -95,25 +68,16 @@
<Run FontWeight="Bold" Text="{ll:Str 反馈频率}" /><LineBreak />
<Run Text="{ll:Str 'VOS 应寻求我反馈按以下频率'}" />
</TextBlock>
<StackPanel Orientation="Horizontal">
<ComboBox
x:Name="CBDiagnosis"
Width="200"
Margin="10,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:SelectionChanged="CBDiagnosis_SelectionChanged"
IsEnabled="False"
SelectedIndex="1"
Style="{DynamicResource StandardComboBoxStyle}">
<ComboBoxItem Content="{ll:Str '每 两百 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 五百 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 一千 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 两千 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 五千 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 一万 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 两万 周期一次'}" />
</ComboBox>
ItemsSource="{Binding DiagnosticSetting.DiagnosisIntervals}"
SelectedItem="{Binding DiagnosticSetting.DiagnosisInterval}"
Style="{DynamicResource ComboBox_BaseStyle}" />
<Label Content="{ll:Str 每周期一次}" Style="{DynamicResource Label_BaseStyle}" />
</StackPanel>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

View File

@ -3,163 +3,209 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:h="clr-namespace:HKW.WPF.Helpers"
xmlns:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF"
xmlns:local="clr-namespace:VPet.Solution.Views.SettingEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:vm="clr-namespace:VPet.Solution.ViewModels.SettingEditor"
Title="ModSettingsPage"
d:DataContext="{d:DesignInstance Type=vm:GraphicsSettingPageVM}"
d:DataContext="{d:DesignInstance Type=vm:ModSettingPageVM}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="15" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" MinWidth="120" />
<ColumnDefinition Width="10" />
<ColumnDefinition MinWidth="200" />
</Grid.ColumnDefinitions>
<ListBox
x:Name="ListMod"
VerticalAlignment="Top"
d:SelectionChanged="ListMod_SelectionChanged"
Background="Transparent"
BorderThickness="0"
SelectionMode="Single"
Style="{DynamicResource SideMenuListBoxStyle}" />
<StackPanel Grid.Column="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox
pu:TextBoxHelper.Watermark="{ll:Str 搜索模组}"
Style="{DynamicResource StandardTextBoxStyle}"
Text="{Binding SearchMod, UpdateSourceTrigger=PropertyChanged}" />
<DataGrid
x:Name="DataGrid_Mods"
Grid.Row="1"
AutoGenerateColumns="False"
CanUserAddRows="False"
ItemsSource="{Binding ShowMods}"
SelectedItem="{Binding CurrentModMoel}">
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding Name}"
ElementStyle="{DynamicResource TextBlock_BaseStyle}"
Header="{ll:Str 名称}"
IsReadOnly="True" />
<DataGridTextColumn
Binding="{Binding State}"
ElementStyle="{DynamicResource TextBlock_BaseStyle}"
Header="{ll:Str 状态}"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
<Button
Grid.Row="2"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ClearFailModsCommand}"
Content="{ll:Str 清除失效模组}"
Style="{DynamicResource Button_BaseStyle}" />
<Button
Grid.Row="3"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ClearModsCommand}"
Content="{ll:Str 清除全部模组}"
Style="{DynamicResource Button_BaseStyle}" />
</Grid>
<Grid
Grid.Column="2"
d:DataContext="{Binding ModSetting.Mods[0]}"
DataContext="{Binding SelectedItem, ElementName=DataGrid_Mods}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="7" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image
x:Name="ImageMOD"
Width="120"
Height="120"
Margin="0,5,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Width="150"
Height="150"
Source="{Binding Image}"
Stretch="Fill" />
<StackPanel Grid.Column="2">
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label
x:Name="LabelModName"
Margin="-5,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
Content="Core"
FontSize="20"
FontWeight="Bold"
Foreground="{DynamicResource PrimaryText}" />
<TextBlock Margin="0,0,0,0" TextWrapping="Wrap">
<Run FontWeight="Bold" Text="{ll:Str '模组作者: '}" /><LineBreak />
<Run x:Name="runMODAuthor" Text="LorisYounger" />
<LineBreak /><Run FontWeight="Bold" Text="{ll:Str '模组版本: '}" /><Run x:Name="runMODVer" Text="1.0" />
<LineBreak /><Run FontWeight="Bold" Text="{ll:Str '游戏版本: '}" /><Run x:Name="runMODGameVer" Text="1.0" />
</TextBlock>
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '模组名称:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Name}" />
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '作者:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Author}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '模组版本:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding ModVersion}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '游戏版本:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding GameVersion}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '模组路径:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding ModPath}" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Margin="-5,0,0,0"
Padding="5,5,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{x:Null}"
Content="{ll:Str MOD介绍}"
FontSize="18"
FontWeight="Bold" />
<ScrollViewer
Height="80"
HorizontalAlignment="Left"
VerticalAlignment="Top"
pu:ScrollViewerHelper.ScrollBarThickness="10"
VerticalScrollBarVisibility="Auto">
FontWeight="Bold"
Style="{DynamicResource Label_BaseStyle}" />
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<TextBlock
x:Name="GameInfo"
VerticalAlignment="Top"
FontSize="14"
Text="这里是MOD的介绍内容,你的介绍就是你的介绍&#xA;"
TextWrapping="Wrap" />
Style="{DynamicResource TextBlock_Wrap}"
Text="{Binding Description}" />
</ScrollViewer>
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
HorizontalAlignment="Left"
Content="{ll:Str 内容}"
FontSize="18"
FontWeight="Bold"
Style="{DynamicResource Label_BaseStyle}" />
<ItemsControl Grid.Row="1" ItemsSource="{Binding Tags}" />
</Grid>
<Grid
Grid.Column="1"
h:ElementHelper.IsEnabled="{Binding IsEnabled, Converter={StaticResource NullToFalse}}"
IsEnabled="False">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
HorizontalAlignment="Left"
Content="{ll:Str 操作}"
FontSize="18"
FontWeight="Bold"
Style="{DynamicResource Label_BaseStyle}" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<Label
Margin="-5,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{x:Null}"
Content="{ll:Str 内容}"
FontSize="18"
FontWeight="Bold" />
<ScrollViewer
Height="140"
Margin="0,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
pu:ScrollViewerHelper.ScrollBarThickness="10"
VerticalScrollBarVisibility="Auto">
<TextBlock
x:Name="GameHave"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="14"
Text="该mod有许多功能&#xA;比如说功能1&#xA;比如说功能1&#xA;比如说功能1&#xA;比如说功能1&#xA;比如说功能1"
TextWrapping="Wrap" />
</ScrollViewer>
<pu:Switch
Content="{ll:Str 启用模组}"
IsChecked="{Binding IsEnabled}"
Style="{DynamicResource Switch_BaseStyle}" />
<pu:Switch
Content="{ll:Str 启用模组代码}"
IsChecked="{Binding IsPass}"
IsEnabled="{Binding IsMsg}"
Style="{DynamicResource Switch_BaseStyle}" />
</StackPanel>
<StackPanel Grid.Column="1">
<Label
Margin="-5,0,0,0"
<Button
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
Content="{ll:Str 操作}"
FontSize="18"
FontWeight="Bold" />
<TextBlock
x:Name="ButtonOpenModFolder"
Margin="0,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonOpenModFolder_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str '所在文件夹'}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
x:Name="ButtonEnable"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonEnable_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str '启用该模组'}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
x:Name="ButtonDisEnable"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonDisEnable_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str '停用该模组'}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
Command="{Binding DataContext.OpenModPathCommand, RelativeSource={RelativeSource AncestorType=Page}}"
CommandParameter="{Binding}"
Content="{ll:Str '打开所在文件夹'}"
Style="{DynamicResource Button_BaseStyle}" />
<!--<TextBlock
x:Name="ButtonPublish"
Margin="0,2,0,0"
HorizontalAlignment="Left"
@ -170,66 +216,18 @@
Foreground="DimGray"
Text="{ll:Str 更新至Steam}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
TextWrapping="Wrap" />-->
<Button
x:Name="ButtonSteam"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonSteam_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="DimGray"
Text="{ll:Str 创意工坊页面}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<ProgressBar
x:Name="ProgressBarUpload"
Height="30"
Margin="0,2,0,0"
VerticalAlignment="Top"
pu:ProgressBarHelper.CornerRadius="2"
pu:ProgressBarHelper.IsPercentVisible="True"
Background="{DynamicResource Primary}"
BorderBrush="{DynamicResource PrimaryDarker}"
BorderThickness="2"
Foreground="{DynamicResource DARKPrimary}"
Visibility="Collapsed"
Value="60" />
<TextBlock
x:Name="ButtonSetting"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonSetting_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str MOD设置}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<Button
x:Name="ButtonAllow"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:Click="ButtonAllow_Click"
Background="#FFFF2C2C"
Content="{ll:Str 启用代码插件}"
FontSize="12"
Foreground="White"
ToolTip="{ll:Str '启用该模组的代码内容,不能保证系统安全性'}" />
Command="{Binding DataContext.OpenSteamCommunityCommand, RelativeSource={RelativeSource AncestorType=Page}}"
CommandParameter="{Binding}"
Content="{ll:Str 打开创意工坊页面}"
Style="{DynamicResource Button_BaseStyle}" />
</StackPanel>
<Button
x:Name="ButtonRestart"
Grid.ColumnSpan="2"
Margin="0,2,0,0"
VerticalAlignment="Bottom"
d:Click="ButtonRestart_Click"
Background="{DynamicResource DARKPrimary}"
Content="{ll:Str 重启软件以应用更改}"
Foreground="{DynamicResource DARKPrimaryText}"
Visibility="Collapsed" />
</Grid>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Grid>
</Page>