From c307d50674124be5763759a9aca23eb5f6803aea Mon Sep 17 00:00:00 2001 From: Hakoyu Date: Wed, 17 Apr 2024 21:35:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VPet.ModMaker.sln | 4 +- VPet.ModMaker/Models/ModMaker.cs | 5 +- VPet.ModMaker/Models/ModMakerInfo.cs | 2 +- .../Models/ModModel/ClickTextModel.cs | 55 +++--- VPet.ModMaker/Models/ModModel/FoodModel.cs | 62 +++--- VPet.ModMaker/Models/ModModel/LowTextModel.cs | 41 +++- VPet.ModMaker/Models/ModModel/ModInfoModel.cs | 177 +++++++----------- .../Models/ModModel/ModUpdataHelper.cs | 4 +- VPet.ModMaker/Models/ModModel/PetModel.cs | 99 +++++----- .../Models/ModModel/SelectTextModel.cs | 70 ++++--- VPet.ModMaker/Models/ModModel/WorkModel.cs | 37 +++- VPet.ModMaker/VPet.ModMaker.csproj | 16 +- .../ModEdit/AnimeEdit/AnimePageVM.cs | 2 + .../ClickTextEdit/ClickTextEditWindowVM.cs | 2 +- .../ModEdit/ClickTextEdit/ClickTextPageVM.cs | 18 +- .../ModEdit/FoodEdit/FoodEditWindowVM.cs | 2 +- .../ViewModels/ModEdit/FoodEdit/FoodPageVM.cs | 27 ++- .../ViewModels/ModEdit/I18nEditWindowVM.cs | 92 ++++++++- .../LowTextEdit/LowTextEditWindowVM.cs | 2 +- .../ModEdit/LowTextEdit/LowTextPageVM.cs | 18 +- .../ViewModels/ModEdit/ModEditWindowVM.cs | 40 +--- .../ViewModels/ModEdit/MoveEdit/MovePageVM.cs | 12 +- .../ModEdit/PetEdit/PetEditWindowVM.cs | 2 +- .../ViewModels/ModEdit/PetEdit/PetPageVM.cs | 22 ++- .../SelectTextEdit/SelectTextEditWindowVM.cs | 3 +- .../SelectTextEdit/SelectTextPageVM.cs | 19 +- .../ModEdit/WorkEdit/WorkEditWindowVM.cs | 2 +- .../ViewModels/ModEdit/WorkEdit/WorkPageVM.cs | 29 ++- .../Views/ModEdit/AddCultureWindow.xaml.cs | 2 +- .../ModEdit/AnimeEdit/AnimeEditWindow.xaml.cs | 6 +- .../AnimeEdit/FoodAnimeEditWindow.xaml.cs | 2 +- .../Views/ModEdit/I18nEditWindow.xaml | 1 + .../Views/ModEdit/I18nEditWindow.xaml.cs | 7 +- .../Views/ModEdit/ModEditWindow.xaml.cs | 6 +- .../ModEdit/PetEdit/PetEditWindow.xaml.cs | 2 +- .../ModEdit/WorkEdit/WorkEditWindow.xaml.cs | 15 +- VPet.ModMaker/Views/ModMakerWindow.xaml.cs | 2 +- 37 files changed, 556 insertions(+), 351 deletions(-) diff --git a/VPet.ModMaker.sln b/VPet.ModMaker.sln index 1f76097..5b2cec8 100644 --- a/VPet.ModMaker.sln +++ b/VPet.ModMaker.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33213.308 @@ -9,12 +8,15 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU + Test|Any CPU = Test|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F804A27-A57E-4799-801C-4DE96BA153BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8F804A27-A57E-4799-801C-4DE96BA153BC}.Debug|Any CPU.Build.0 = Debug|Any CPU {8F804A27-A57E-4799-801C-4DE96BA153BC}.Release|Any CPU.ActiveCfg = Release|Any CPU {8F804A27-A57E-4799-801C-4DE96BA153BC}.Release|Any CPU.Build.0 = Release|Any CPU + {8F804A27-A57E-4799-801C-4DE96BA153BC}.Test|Any CPU.ActiveCfg = Test|Any CPU + {8F804A27-A57E-4799-801C-4DE96BA153BC}.Test|Any CPU.Build.0 = Test|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VPet.ModMaker/Models/ModMaker.cs b/VPet.ModMaker/Models/ModMaker.cs index f1ddf35..8041211 100644 --- a/VPet.ModMaker/Models/ModMaker.cs +++ b/VPet.ModMaker/Models/ModMaker.cs @@ -50,7 +50,10 @@ public class ModMaker : MainPlugin ModMakerInfo.GameVersion = MW.version; // 载入本体宠物 foreach (var pet in MW.Pets) - ModMakerInfo.MainPets.TryAdd(pet.Name, new(pet, true)); + ModMakerInfo.MainPets.TryAdd( + pet.Name, + new(pet, true) { I18nResource = ModInfoModel.Current.I18nResource } + ); //Maker.ModMaker = this; Maker.Show(); Maker.Closed += Maker_Closed; diff --git a/VPet.ModMaker/Models/ModMakerInfo.cs b/VPet.ModMaker/Models/ModMakerInfo.cs index de234fa..17ec79f 100644 --- a/VPet.ModMaker/Models/ModMakerInfo.cs +++ b/VPet.ModMaker/Models/ModMakerInfo.cs @@ -36,7 +36,7 @@ public static class ModMakerInfo /// /// 本体的宠物 /// - /// (PetId, PetModel) + /// (PetID, PetModel) /// /// public static Dictionary MainPets { get; } = new(); diff --git a/VPet.ModMaker/Models/ModModel/ClickTextModel.cs b/VPet.ModMaker/Models/ModModel/ClickTextModel.cs index 5535b02..28b8e5c 100644 --- a/VPet.ModMaker/Models/ModModel/ClickTextModel.cs +++ b/VPet.ModMaker/Models/ModModel/ClickTextModel.cs @@ -19,12 +19,7 @@ namespace VPet.ModMaker.Models; /// public class ClickTextModel : ObservableObjectX { - public ClickTextModel() - { - ModInfoModel.Current.I18nResource.I18nObjectInfos.Add( - new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Text), true)]) - ); - } + public ClickTextModel() { } public ClickTextModel(ClickTextModel clickText) : this() @@ -124,11 +119,35 @@ public class ClickTextModel : ObservableObjectX #endregion #region I18nData + [AdaptIgnore] + private I18nResource _i18nResource = null!; + + [AdaptIgnore] + public required I18nResource I18nResource + { + get => _i18nResource; + set + { + if (_i18nResource is not null) + I18nResource.I18nObjectInfos.Remove(this); + _i18nResource = value; + InitializeI18nResource(); + } + } + + public void InitializeI18nResource() + { + I18nResource.I18nObjectInfos.Add( + this, + new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Text), true),]) + ); + } + [AdaptIgnore] public string Text { - get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ID); + set => I18nResource.SetCurrentCultureData(ID, value); } #endregion @@ -224,25 +243,9 @@ public class ClickTextModel : ObservableObjectX /// 体力 /// public ObservableRange Strength { get; } = new(0, int.MaxValue); -} -public class I18nClickTextModel : ObservableObjectX, ICloneable -{ - #region Text - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private string _text = string.Empty; - - public string Text + public void Close() { - get => _text; - set => SetProperty(ref _text, value); + I18nResource.I18nObjectInfos.Remove(this); } - #endregion - - public I18nClickTextModel Clone() - { - return this.Adapt(); - } - - object ICloneable.Clone() => Clone(); } diff --git a/VPet.ModMaker/Models/ModModel/FoodModel.cs b/VPet.ModMaker/Models/ModModel/FoodModel.cs index 992355a..d23aa91 100644 --- a/VPet.ModMaker/Models/ModModel/FoodModel.cs +++ b/VPet.ModMaker/Models/ModModel/FoodModel.cs @@ -26,19 +26,9 @@ public class FoodModel : ObservableObjectX public FoodModel() { PropertyChangedX += FoodModel_PropertyChangedX; - ModInfoModel.Current.I18nResource.I18nObjectInfos.Add( - new( - this, - OnPropertyChanged, - [ - (nameof(ID), ID, nameof(Name), true), - (nameof(DescriptionID), DescriptionID, nameof(Description), true) - ] - ) - ); } - private static FrozenSet _notifyReferencePrice = FrozenSet.ToFrozenSet( + private static readonly FrozenSet _notifyReferencePrice = FrozenSet.ToFrozenSet( [ nameof(Strength), nameof(StrengthFood), @@ -116,22 +106,50 @@ public class FoodModel : ObservableObjectX #endregion #region I18nData + + [AdaptIgnore] + private I18nResource _i18nResource = null!; + + [AdaptIgnore] + public required I18nResource I18nResource + { + get => _i18nResource; + set + { + if (_i18nResource is not null) + I18nResource.I18nObjectInfos.Remove(this); + _i18nResource = value; + InitializeI18nResource(); + } + } + + public void InitializeI18nResource() + { + I18nResource.I18nObjectInfos.Add( + this, + new( + this, + OnPropertyChanged, + [ + (nameof(ID), ID, nameof(Name), true), + (nameof(DescriptionID), DescriptionID, nameof(Description), true) + ] + ) + ); + } + [AdaptIgnore] public string Name { - get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ID); + set => I18nResource.SetCurrentCultureData(ID, value); } [AdaptIgnore] public string Description { - get => - ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault( - DescriptionID, - string.Empty - ); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(DescriptionID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(DescriptionID, string.Empty); + set => I18nResource.SetCurrentCultureData(DescriptionID, value); } #endregion @@ -345,10 +363,6 @@ public class FoodModel : ObservableObjectX public void Close() { Image?.CloseStream(); - var item = ModInfoModel.Current.I18nResource.I18nObjectInfos.FirstOrDefault(i => - i.Source == this - ); - if (item is not null) - ModInfoModel.Current.I18nResource.I18nObjectInfos.Remove(item); + I18nResource.I18nObjectInfos.Remove(this); } } diff --git a/VPet.ModMaker/Models/ModModel/LowTextModel.cs b/VPet.ModMaker/Models/ModModel/LowTextModel.cs index da05fa7..b59abd0 100644 --- a/VPet.ModMaker/Models/ModModel/LowTextModel.cs +++ b/VPet.ModMaker/Models/ModModel/LowTextModel.cs @@ -18,12 +18,7 @@ namespace VPet.ModMaker.Models; /// public class LowTextModel : ObservableObjectX { - public LowTextModel() - { - ModInfoModel.Current.I18nResource.I18nObjectInfos.Add( - new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Text), true)]) - ); - } + public LowTextModel() { } public LowTextModel(LowTextModel lowText) : this() @@ -56,6 +51,7 @@ public class LowTextModel : ObservableObjectX Enum.GetValues().ToFrozenSet(); #region ID + [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string _id = string.Empty; @@ -71,11 +67,35 @@ public class LowTextModel : ObservableObjectX #endregion #region I18nData + [AdaptIgnore] + private I18nResource _i18nResource = null!; + + [AdaptIgnore] + public required I18nResource I18nResource + { + get => _i18nResource; + set + { + if (_i18nResource is not null) + I18nResource.I18nObjectInfos.Remove(this); + _i18nResource = value; + InitializeI18nResource(); + } + } + + public void InitializeI18nResource() + { + I18nResource.I18nObjectInfos.Add( + this, + new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Text), true)]) + ); + } + [AdaptIgnore] public string Text { - get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ID); + set => I18nResource.SetCurrentCultureData(ID, value); } #endregion @@ -128,4 +148,9 @@ public class LowTextModel : ObservableObjectX { return this.Adapt(); } + + public void Close() + { + I18nResource.I18nObjectInfos.Remove(this); + } } diff --git a/VPet.ModMaker/Models/ModModel/ModInfoModel.cs b/VPet.ModMaker/Models/ModModel/ModInfoModel.cs index 3654025..56dc656 100644 --- a/VPet.ModMaker/Models/ModModel/ModInfoModel.cs +++ b/VPet.ModMaker/Models/ModModel/ModInfoModel.cs @@ -34,6 +34,19 @@ public class ModInfoModel : ObservableObjectX Current = this; PropertyChanged += ModInfoModel_PropertyChanged; Pets.CollectionChanged += Pets_CollectionChanged; + I18nResource.PropertyChanged += I18nResource_PropertyChanged; + I18nResource.Cultures.SetChanged += Cultures_SetChanged; + I18nResource.I18nObjectInfos.Add( + this, + new( + this, + OnPropertyChanged, + [ + (nameof(ID), ID, nameof(Name), true), + (nameof(DescriptionID), DescriptionID, nameof(Description), true) + ] + ) + ); } public ModInfoModel(ModLoader loader) @@ -51,28 +64,28 @@ public class ModInfoModel : ObservableObjectX if (File.Exists(imagePath)) Image = NativeUtils.LoadImageToMemoryStream(imagePath); foreach (var food in loader.Foods.Where(m => string.IsNullOrWhiteSpace(m.Name) is false)) - Foods.Add(new(food)); + Foods.Add(new(food) { I18nResource = I18nResource }); foreach ( var clickText in loader.ClickTexts.Where(m => string.IsNullOrWhiteSpace(m.Text) is false ) ) - ClickTexts.Add(new(clickText)); + ClickTexts.Add(new(clickText) { I18nResource = I18nResource }); foreach ( var lowText in loader.LowTexts.Where(m => string.IsNullOrWhiteSpace(m.Text) is false) ) - LowTexts.Add(new(lowText)); + LowTexts.Add(new(lowText) { I18nResource = I18nResource }); foreach ( var selectText in loader.SelectTexts.Where(m => string.IsNullOrWhiteSpace(m.Text) is false ) ) - SelectTexts.Add(new(selectText)); + SelectTexts.Add(new(selectText) { I18nResource = I18nResource }); // 载入模组宠物 foreach (var pet in loader.Pets) { - var petModel = new PetModel(pet); + var petModel = new PetModel(pet) { I18nResource = I18nResource }; // 如果检测到本体存在同名宠物 if (ModMakerInfo.MainPets.TryGetValue(petModel.ID, out var mainPet)) { @@ -113,12 +126,8 @@ public class ModInfoModel : ObservableObjectX if (Pets.All(i => i.ID != pet.Key)) Pets.Insert(0, pet.Value); } - - // 载入本地化模组信息 - //foreach (var lang in loader.I18nDatas) - // I18nDatas.Add(lang.Key, lang.Value); - //OtherI18nDatas = loader.I18nDatas; - + if (loader.I18nDatas.HasValue() is false) + return; LoadI18nDatas(loader); RefreshAllID(); if (I18nResource.CultureDatas.HasValue()) @@ -143,9 +152,18 @@ public class ModInfoModel : ObservableObjectX /// public static ModInfoModel Current { get; set; } = new(); + /// + /// I18n资源 + /// public I18nResource I18nResource { get; } = new() { FillDefaultValueForNewCulture = true, DefaultValue = string.Empty }; + /// + /// 临时I18n资源, 用于新建的项目 + /// + public I18nResource TempI18nResource { get; } = + new() { FillDefaultValueForNewCulture = true, DefaultValue = string.Empty }; + #region I18nData public string Name { @@ -339,6 +357,41 @@ public class ModInfoModel : ObservableObjectX #endregion #endregion + private void I18nResource_PropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(I18nResource.CurrentCulture)) + { + TempI18nResource.CurrentCulture = I18nResource.CurrentCulture; + } + } + + private void Cultures_SetChanged( + IObservableSet sender, + NotifySetChangeEventArgs e + ) + { + if (e.Action is SetChangeAction.Clear) + { + TempI18nResource.ClearCulture(); + } + else + { + if (e.OldItems is not null) + { + foreach (var item in e.OldItems) + { + TempI18nResource.RemoveCulture(item); + } + } + if (e.NewItems is not null) + { + foreach (var item in e.NewItems) + { + TempI18nResource.AddCulture(item); + } + } + } + } private void Pets_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { @@ -448,9 +501,6 @@ public class ModInfoModel : ObservableObjectX /// private void LoadI18nDatas(ModLoader modLoader) { - if (modLoader.I18nDatas.HasValue() is false) - return; - foreach (var cultureDatas in modLoader.I18nDatas) { var culture = CultureInfo.GetCultureInfo(cultureDatas.Key); @@ -460,106 +510,11 @@ public class ModInfoModel : ObservableObjectX } if (I18nResource.SetCurrentCulture(CultureInfo.CurrentCulture) is false) I18nResource.SetCurrentCulture(I18nResource.Cultures.First()); - I18nResource.I18nObjectInfos.Add( - new( - this, - OnPropertyChanged, - [ - (nameof(ID), ID, nameof(Name), true), - (nameof(DescriptionID), DescriptionID, nameof(Description), true) - ] - ) - ); - //foreach (var lang in I18nDatas.Keys.Union(OtherI18nDatas.Keys)) - //{ - // if (I18nHelper.Current.CultureNames.Contains(lang) is false) - // I18nHelper.Current.CultureNames.Add(lang); - //} - //if (I18nHelper.Current.CultureNames.Count == 0) - // return; - //I18nHelper.Current.CultureName = I18nHelper.Current.CultureNames.First(); - //foreach (var i18nData in OtherI18nDatas) - //{ - // LoadFoodI18nData(i18nData.Key, i18nData.Value); - // LoadLowTextI18nData(i18nData.Key, i18nData.Value); - // LoadClickTextI18nData(i18nData.Key, i18nData.Value); - // LoadSelectTextI18nData(i18nData.Key, i18nData.Value); - // LoadPetI18nData(i18nData.Key, i18nData.Value); - //} } - //private void LoadFoodI18nData(string key, Dictionary i18nData) - //{ - // foreach (var food in Foods) - // { - // if (food.I18nDatas.TryGetValue(key, out var data) is false) - // continue; - // if (i18nData.TryGetValue(food.ID, out var name)) - // data.Name = name; - // if (i18nData.TryGetValue(food.DescriptionID, out var description)) - // data.Description = description; - // } - //} - - //private void LoadLowTextI18nData(string key, Dictionary i18nData) - //{ - // foreach (var lowText in LowTexts) - // { - // if (lowText.I18nDatas.TryGetValue(key, out var data) is false) - // continue; - // if (i18nData.TryGetValue(lowText.ID, out var text)) - // data.Text = text; - // } - //} - - //private void LoadClickTextI18nData(string key, Dictionary i18nData) - //{ - // foreach (var clickText in ClickTexts) - // { - // if (clickText.I18nDatas.TryGetValue(key, out var data) is false) - // continue; - // if (i18nData.TryGetValue(clickText.ID, out var text)) - // data.Text = text; - // } - //} - - //private void LoadSelectTextI18nData(string key, Dictionary i18nData) - //{ - // foreach (var selectText in SelectTexts) - // { - // if (selectText.I18nDatas.TryGetValue(key, out var data) is false) - // continue; - // if (i18nData.TryGetValue(selectText.ID, out var text)) - // data.Text = text; - // if (i18nData.TryGetValue(selectText.ChooseID, out var choose)) - // data.Choose = choose; - // } - //} - - //private void LoadPetI18nData(string key, Dictionary i18nData) - //{ - // foreach (var pet in Pets) - // { - // if (pet.I18nDatas.TryGetValue(key, out var data) is false) - // continue; - // if (i18nData.TryGetValue(pet.ID, out var name)) - // data.Name = name; - // if (i18nData.TryGetValue(pet.PetNameID, out var petName)) - // data.PetName = petName; - // if (i18nData.TryGetValue(pet.DescriptionID, out var description)) - // data.Description = description; - // foreach (var work in pet.Works) - // { - // if (work.I18nDatas.TryGetValue(key, out var workData) is false) - // continue; - // if (i18nData.TryGetValue(work.ID, out var workName)) - // workData.Name = workName; - // } - // } - //} - - private void RefreshAllID() + public void RefreshAllID() { + RefreshID(); foreach (var food in Foods) food.RefreshID(); foreach (var selectText in SelectTexts) diff --git a/VPet.ModMaker/Models/ModModel/ModUpdataHelper.cs b/VPet.ModMaker/Models/ModModel/ModUpdataHelper.cs index c101fef..36cdb0f 100644 --- a/VPet.ModMaker/Models/ModModel/ModUpdataHelper.cs +++ b/VPet.ModMaker/Models/ModModel/ModUpdataHelper.cs @@ -27,7 +27,7 @@ public static class ModUpdataHelper /// 可以升级为 不可以为 public static bool CanUpdata(ModInfoModel mod) { - if (mod.ModVersion >= LastVersion) + if (mod.GameVersion >= LastVersion) return false; return true; } @@ -44,7 +44,7 @@ public static class ModUpdataHelper return false; foreach (var action in UpdataAction) { - if (mod.ModVersion >= action.Key) + if (mod.GameVersion >= action.Key) continue; try { diff --git a/VPet.ModMaker/Models/ModModel/PetModel.cs b/VPet.ModMaker/Models/ModModel/PetModel.cs index 882537c..0af7cd4 100644 --- a/VPet.ModMaker/Models/ModModel/PetModel.cs +++ b/VPet.ModMaker/Models/ModModel/PetModel.cs @@ -30,17 +30,6 @@ public class PetModel : ObservableObjectX PropertyChanged += PetModel_PropertyChanged; Animes.PropertyChanged += Animes_PropertyChanged; FoodAnimes.PropertyChanged += FoodAnimes_PropertyChanged; - ModInfoModel.Current.I18nResource.I18nObjectInfos.Add( - new( - this, - OnPropertyChanged, - [ - (nameof(ID), ID, nameof(Name), true), - (nameof(PetNameID), PetNameID, nameof(Name), true), - (nameof(DescriptionID), DescriptionID, nameof(Description), true) - ] - ) - ); } private void PetModel_PropertyChanged(object? sender, PropertyChangedEventArgs e) @@ -126,12 +115,12 @@ public class PetModel : ObservableObjectX return; foreach (var work in loader.Config.Works) - Works.Add(new(work)); + Works.Add(new(work) { I18nResource = ModInfoModel.Current.I18nResource }); foreach (var move in loader.Config.Moves) Moves.Add(new(move)); } - public static PetModel Current { get; } = new(); + public static PetModel Current { get; } = null!; #region FromMain [DebuggerBrowsable(DebuggerBrowsableState.Never)] @@ -164,7 +153,7 @@ public class PetModel : ObservableObjectX } } #endregion - #region PetNameId + #region PetNameID [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string _petNameID = string.Empty; @@ -178,7 +167,7 @@ public class PetModel : ObservableObjectX } #endregion - #region DescriptionId + #region DescriptionID [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string _descriptionID = string.Empty; @@ -193,33 +182,57 @@ public class PetModel : ObservableObjectX #endregion #region I18nData + [AdaptIgnore] + private I18nResource _i18nResource = null!; + + [AdaptIgnore] + public required I18nResource I18nResource + { + get => _i18nResource; + set + { + if (_i18nResource is not null) + I18nResource.I18nObjectInfos.Remove(this); + _i18nResource = value; + InitializeI18nResource(); + } + } + + public void InitializeI18nResource() + { + I18nResource.I18nObjectInfos.Add( + this, + new( + this, + OnPropertyChanged, + [ + (nameof(ID), ID, nameof(Name), true), + (nameof(PetNameID), PetNameID, nameof(PetName), true), + (nameof(DescriptionID), DescriptionID, nameof(Description), true) + ] + ) + ); + } + [AdaptIgnore] public string Name { - get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ID); + set => I18nResource.SetCurrentCultureData(ID, value); } [AdaptIgnore] public string PetName { - get => - ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault( - PetNameID, - string.Empty - ); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(PetNameID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(PetNameID); + set => I18nResource.SetCurrentCultureData(PetNameID, value); } [AdaptIgnore] public string Description { - get => - ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault( - DescriptionID, - string.Empty - ); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(DescriptionID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(DescriptionID); + set => I18nResource.SetCurrentCultureData(DescriptionID, value); } #endregion @@ -357,6 +370,11 @@ public class PetModel : ObservableObjectX anime.Close(); } + public void CloseI18nResource() + { + I18nResource.I18nObjectInfos.Remove(this); + } + #region Save /// @@ -382,17 +400,6 @@ public class PetModel : ObservableObjectX /// 路径 public void Save(string path) { - // TODO - //foreach (var cultureName in I18nHelper.Current.CultureNames) - //{ - // ModInfoModel.SaveI18nDatas[cultureName].TryAdd(ID, I18nDatas[cultureName].Name); - // ModInfoModel - // .SaveI18nDatas[cultureName] - // .TryAdd(PetNameID, I18nDatas[cultureName].PetName); - // ModInfoModel - // .SaveI18nDatas[cultureName] - // .TryAdd(DescriptionID, I18nDatas[cultureName].Description); - //} var petFile = Path.Combine(path, $"{ID}.lps"); if (File.Exists(petFile) is false) File.Create(petFile).Close(); @@ -439,14 +446,7 @@ public class PetModel : ObservableObjectX { foreach (var work in Works) { - //TODO - //lps.Add(LPSConvert.SerializeObjectToLine(work.ToWork(), "work")); - //foreach (var cultureName in I18nHelper.Current.CultureNames) - //{ - // ModInfoModel - // .SaveI18nDatas[cultureName] - // .TryAdd(work.ID, work.I18nDatas[cultureName].Name); - //} + lps.Add(LPSConvert.SerializeObjectToLine(work.ToWork(), "work")); } } @@ -505,7 +505,8 @@ public class PetModel : ObservableObjectX new Sub("petname", PetNameID) } ); - lps.Add(new Line("tag", Tags)); + if (string.IsNullOrWhiteSpace(Tags) is false) + lps.Add(new Line("tag", Tags)); } private void SavePetTouchHeadInfo(LPS lps) diff --git a/VPet.ModMaker/Models/ModModel/SelectTextModel.cs b/VPet.ModMaker/Models/ModModel/SelectTextModel.cs index f276d3d..8ac4dce 100644 --- a/VPet.ModMaker/Models/ModModel/SelectTextModel.cs +++ b/VPet.ModMaker/Models/ModModel/SelectTextModel.cs @@ -18,19 +18,7 @@ namespace VPet.ModMaker.Models; /// public class SelectTextModel : ObservableObjectX { - public SelectTextModel() - { - ModInfoModel.Current.I18nResource.I18nObjectInfos.Add( - new( - this, - OnPropertyChanged, - [ - (nameof(ID), ID, nameof(Text), true), - (nameof(ChooseID), ChooseID, nameof(Choose), true) - ] - ) - ); - } + public SelectTextModel() { } public SelectTextModel(SelectTextModel model) : this() @@ -120,37 +108,64 @@ public class SelectTextModel : ObservableObjectX } #endregion - #region ChooseId + #region ChooseID [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private string _chooseId = string.Empty; + private string _chooseID = string.Empty; /// /// 选择Id /// public string ChooseID { - get => _chooseId; - set => SetProperty(ref _chooseId, value); + get => _chooseID; + set => SetProperty(ref _chooseID, value); } #endregion #region I18nData + [AdaptIgnore] + private I18nResource _i18nResource = null!; + + [AdaptIgnore] + public required I18nResource I18nResource + { + get => _i18nResource; + set + { + if (_i18nResource is not null) + I18nResource.I18nObjectInfos.Remove(this); + _i18nResource = value; + InitializeI18nResource(); + } + } + + public void InitializeI18nResource() + { + I18nResource.I18nObjectInfos.Add( + this, + new( + this, + OnPropertyChanged, + [ + (nameof(ID), ID, nameof(Text), true), + (nameof(ChooseID), ChooseID, nameof(Choose), true) + ] + ) + ); + } + [AdaptIgnore] public string Text { - get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ID); + set => I18nResource.SetCurrentCultureData(ID, value); } [AdaptIgnore] public string Choose { - get => - ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault( - ChooseID, - string.Empty - ); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ChooseID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ChooseID, string.Empty); + set => I18nResource.SetCurrentCultureData(ChooseID, value); } #endregion @@ -239,4 +254,9 @@ public class SelectTextModel : ObservableObjectX StrengthMax = Strength.Max, }; } + + public void Close() + { + I18nResource.I18nObjectInfos.Remove(this); + } } diff --git a/VPet.ModMaker/Models/ModModel/WorkModel.cs b/VPet.ModMaker/Models/ModModel/WorkModel.cs index d7defe7..8aed4cb 100644 --- a/VPet.ModMaker/Models/ModModel/WorkModel.cs +++ b/VPet.ModMaker/Models/ModModel/WorkModel.cs @@ -23,9 +23,6 @@ public class WorkModel : ObservableObjectX public WorkModel() { PropertyChanged += WorkModel_PropertyChanged; - ModInfoModel.Current.I18nResource.I18nObjectInfos.Add( - new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Name), true)]) - ); } private static readonly FrozenSet _notifyIsOverLoad = FrozenSet.ToFrozenSet( @@ -126,11 +123,35 @@ public class WorkModel : ObservableObjectX #endregion #region I18nData + [AdaptIgnore] + private I18nResource _i18nResource = null!; + + [AdaptIgnore] + public required I18nResource I18nResource + { + get => _i18nResource; + set + { + if (_i18nResource is not null) + I18nResource.I18nObjectInfos.Remove(this); + _i18nResource = value; + InitializeI18nResource(); + } + } + + public void InitializeI18nResource() + { + I18nResource.I18nObjectInfos.Add( + this, + new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Name), true),]) + ); + } + [AdaptIgnore] public string Name { - get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID); - set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value); + get => I18nResource.GetCurrentCultureDataOrDefault(ID); + set => I18nResource.SetCurrentCultureData(ID, value); } #endregion @@ -459,10 +480,6 @@ public class WorkModel : ObservableObjectX public void Close() { //Image?.CloseStream(); - var item = ModInfoModel.Current.I18nResource.I18nObjectInfos.FirstOrDefault(i => - i.Source == this - ); - if (item is not null) - ModInfoModel.Current.I18nResource.I18nObjectInfos.Remove(item); + I18nResource.I18nObjectInfos.Remove(this); } } diff --git a/VPet.ModMaker/VPet.ModMaker.csproj b/VPet.ModMaker/VPet.ModMaker.csproj index 4908813..3a76fe5 100644 --- a/VPet.ModMaker/VPet.ModMaker.csproj +++ b/VPet.ModMaker/VPet.ModMaker.csproj @@ -11,11 +11,23 @@ true preview enable + Debug;Release;Test - + + + ..\..\HKW.Utils\HKW.Utils\bin\Debug\net8.0\HKW.Utils.dll + + + ..\..\HKW.WPF\HKW.WPF\bin\Debug\net8.0-windows\HKW.WPF.dll + + + + + + @@ -28,8 +40,6 @@ - - \ No newline at end of file diff --git a/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs index 3f0ad1d..afbc64d 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs @@ -142,6 +142,8 @@ public class AnimePageVM : ObservableObjectX private void InitializeAllAnimes() { AllAnimes.Clear(); + if (CurrentPet is null) + return; foreach (var item in Animes) AllAnimes.Add(item); foreach (var item in FoodAnimes) diff --git a/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextEditWindowVM.cs index ae344d4..575462e 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextEditWindowVM.cs @@ -26,7 +26,7 @@ public class ClickTextEditWindowVM : ObservableObjectX #region ClickText [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private ClickTextModel _clickText = new(); + private ClickTextModel _clickText = new() { I18nResource = ModInfoModel.Current.I18nResource }; /// /// 点击文本 diff --git a/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs index c23342d..40b4587 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using HKW.HKWUtils.Extensions; using HKW.HKWUtils.Observable; using LinePutScript.Localization.WPF; using VPet.ModMaker.Models; @@ -22,6 +23,7 @@ public class ClickTextPageVM : ObservableObjectX Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; + ClickTexts.BindingList(ModInfoModel.Current.ClickTexts); AddCommand.ExecuteCommand += AddCommand_ExecuteCommand; EditCommand.ExecuteCommand += EditCommand_ExecuteCommand; RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteCommand; @@ -100,11 +102,22 @@ public class ClickTextPageVM : ObservableObjectX var window = new ClickTextEditWindow(); var vm = window.ViewModel; vm.OldClickText = model; - var newLowTest = vm.ClickText = new(model); + var newModel = vm.ClickText = new(model) + { + I18nResource = ModInfoModel.Current.TempI18nResource + }; + model.I18nResource.CopyDataTo(newModel.I18nResource, model.ID, true); window.ShowDialog(); if (window.IsCancel) + { + newModel.I18nResource.ClearCultureData(); + newModel.Close(); return; - ClickTexts[ClickTexts.IndexOf(model)] = newLowTest; + } + newModel.I18nResource.CopyDataTo(ModInfoModel.Current.I18nResource, true); + newModel.I18nResource = ModInfoModel.Current.I18nResource; + ClickTexts[ClickTexts.IndexOf(model)] = newModel; + model.Close(); } /// @@ -116,5 +129,6 @@ public class ClickTextPageVM : ObservableObjectX if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No) return; ClickTexts.Remove(model); + model.Close(); } } diff --git a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs index 2b33028..c15d65f 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs @@ -36,7 +36,7 @@ public class FoodEditWindowVM : ObservableObjectX #region Food [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private FoodModel _food = new(); + private FoodModel _food = new() { I18nResource = ModInfoModel.Current.I18nResource }; public FoodModel Food { diff --git a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs index 9583795..b24ad5f 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using HKW.HKWUtils.Extensions; using HKW.HKWUtils.Observable; using LinePutScript.Localization.WPF; using VPet.ModMaker.Models; @@ -24,6 +25,7 @@ public class FoodPageVM : ObservableObjectX Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; + Foods.BindingList(ModInfoModel.Current.Foods); AddCommand.ExecuteCommand += AddCommand_ExecuteCommand; EditCommand.ExecuteCommand += EditCommand_ExecuteCommand; @@ -76,23 +78,34 @@ public class FoodPageVM : ObservableObjectX Foods.Add(vm.Food); } - public void EditCommand_ExecuteCommand(FoodModel food) + public void EditCommand_ExecuteCommand(FoodModel model) { var window = new FoodEditWindow(); var vm = window.ViewModel; - vm.OldFood = food; - var newFood = vm.Food = new(food); + vm.OldFood = model; + var newModel = vm.Food = new(model) + { + I18nResource = ModInfoModel.Current.TempI18nResource + }; + model.I18nResource.CopyDataTo(newModel.I18nResource, [model.ID, model.DescriptionID], true); window.ShowDialog(); if (window.IsCancel) + { + newModel.I18nResource.ClearCultureData(); + newModel.Close(); return; - Foods[Foods.IndexOf(food)] = newFood; - food.Close(); + } + newModel.I18nResource.CopyDataTo(ModInfoModel.Current.I18nResource, true); + newModel.I18nResource = ModInfoModel.Current.I18nResource; + Foods[Foods.IndexOf(model)] = newModel; + model.Close(); } - private void RemoveCommand_ExecuteCommand(FoodModel food) + private void RemoveCommand_ExecuteCommand(FoodModel model) { if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No) return; - Foods.Remove(food); + Foods.Remove(model); + model.Close(); } } diff --git a/VPet.ModMaker/ViewModels/ModEdit/I18nEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/I18nEditWindowVM.cs index 62269e9..7ac0181 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/I18nEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/I18nEditWindowVM.cs @@ -23,16 +23,27 @@ public class I18nEditWindowVM : ObservableObjectX SearchTarget = SearchTargets.First(); PropertyChanged += I18nEditWindowVM_PropertyChanged; - ModInfoModel.Current.I18nResource.Cultures.SetChanged -= Cultures_SetChanged; - ModInfoModel.Current.I18nResource.Cultures.SetChanged += Cultures_SetChanged; + I18nResource.Cultures.SetChanged -= Cultures_SetChanged; + I18nResource.Cultures.SetChanged += Cultures_SetChanged; + + I18nResource.CultureDatas.DictionaryChanged -= CultureDatas_DictionaryChanged; + I18nResource.CultureDatas.DictionaryChanged += CultureDatas_DictionaryChanged; I18nDatas = new() { Filter = DataFilter, FilteredList = [] }; - foreach (var data in ModInfoModel.Current.I18nResource.CultureDatas.Values) + foreach (var data in I18nResource.CultureDatas.Values) + { I18nDatas.Add(data); - foreach (var culture in ModInfoModel.Current.I18nResource.Cultures) + data.DictionaryChanged += Data_DictionaryChanged; + } + foreach (var culture in I18nResource.Cultures) SearchTargets.Add(culture.Name); } + public I18nResource I18nResource { get; set; } = + ModInfoModel.Current.I18nResource; + + public bool CellEdit { get; set; } = false; + #region Search [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string _search = string.Empty; @@ -97,7 +108,7 @@ public class I18nEditWindowVM : ObservableObjectX private void Cultures_SetChanged( IObservableSet sender, - NotifySetChangedEventArgs e + NotifySetChangeEventArgs e ) { if (e.Action is SetChangeAction.Add) @@ -122,6 +133,46 @@ public class I18nEditWindowVM : ObservableObjectX } } + private void CultureDatas_DictionaryChanged( + IObservableDictionary> sender, + NotifyDictionaryChangeEventArgs> e + ) + { + if (e.Action is DictionaryChangeAction.Add) + { + if (e.TryGetNewPair(out var newPair) is false) + return; + I18nDatas.Add(newPair.Value); + newPair.Value.DictionaryChanged -= Data_DictionaryChanged; + newPair.Value.DictionaryChanged += Data_DictionaryChanged; + } + else if (e.Action is DictionaryChangeAction.Remove) + { + if (e.TryGetOldPair(out var oldPair) is false) + return; + I18nDatas.Remove(oldPair.Value); + oldPair.Value.DictionaryChanged -= Data_DictionaryChanged; + } + else if (e.Action is DictionaryChangeAction.Replace) + { + if (e.TryGetNewPair(out var newPair) is false) + return; + if (e.TryGetOldPair(out var oldPair) is false) + return; + if (I18nDatas.TryFind(0, i => i.Key == newPair.Key, out var itemInfo) is false) + return; + I18nDatas.RemoveAt(itemInfo.Index); + I18nDatas.Insert(itemInfo.Index, newPair.Value); + oldPair.Value.DictionaryChanged -= Data_DictionaryChanged; + newPair.Value.DictionaryChanged -= Data_DictionaryChanged; + newPair.Value.DictionaryChanged += Data_DictionaryChanged; + } + else if (e.Action is DictionaryChangeAction.Clear) + { + I18nDatas.Clear(); + } + } + private void I18nEditWindowVM_PropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(Search)) @@ -134,6 +185,29 @@ public class I18nEditWindowVM : ObservableObjectX } } + private void Data_DictionaryChanged( + IObservableDictionary sender, + NotifyDictionaryChangeEventArgs e + ) + { + if (sender is not ObservableCultureDataDictionary cultureDatas) + return; + // 刷新修改后的数据 + if (e.Action is DictionaryChangeAction.Replace) + { + if (CellEdit) + { + // 防止在编辑单元格时重复响应 + CellEdit = false; + return; + } + if (I18nDatas.TryFind(0, i => i.Key == cultureDatas.Key, out var itemInfo) is false) + return; + I18nDatas.RemoveAt(itemInfo.Index); + I18nDatas.Insert(itemInfo.Index, cultureDatas); + } + } + #region Event private void AddCulture(string culture) { @@ -145,10 +219,10 @@ public class I18nEditWindowVM : ObservableObjectX CultureChanged?.Invoke(culture, string.Empty); } - private void ReplaceCulture(string oldCulture, string newCulture) - { - CultureChanged?.Invoke(oldCulture, newCulture); - } + //private void ReplaceCulture(string oldCulture, string newCulture) + //{ + // CultureChanged?.Invoke(oldCulture, newCulture); + //} public event CultureChangedEventHandler? CultureChanged; #endregion diff --git a/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextEditWindowVM.cs index 47e3d63..05a5b47 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextEditWindowVM.cs @@ -22,7 +22,7 @@ public class LowTextEditWindowVM : ObservableObjectX #region LowText [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private LowTextModel _lowText = new(); + private LowTextModel _lowText = new() { I18nResource = ModInfoModel.Current.I18nResource }; public LowTextModel LowText { diff --git a/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs index 38f59c7..b6e783e 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs @@ -8,6 +8,7 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using System.Windows; +using HKW.HKWUtils.Extensions; using HKW.HKWUtils.Observable; using LinePutScript.Localization.WPF; using VPet.ModMaker.Models; @@ -24,6 +25,7 @@ public class LowTextPageVM : ObservableObjectX Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; + LowTexts.BindingList(ModInfoModel.Current.LowTexts); AddCommand.ExecuteCommand += AddCommand_ExecuteCommand; EditCommand.ExecuteCommand += EditCommand_ExecuteCommand; @@ -78,11 +80,22 @@ public class LowTextPageVM : ObservableObjectX var window = new LowTextEditWindow(); var vm = window.ViewModel; vm.OldLowText = model; - var newLowTest = vm.LowText = new(model); + var newModel = vm.LowText = new(model) + { + I18nResource = ModInfoModel.Current.TempI18nResource + }; + model.I18nResource.CopyDataTo(newModel.I18nResource, model.ID, true); window.ShowDialog(); if (window.IsCancel) + { + newModel.I18nResource.ClearCultureData(); + newModel.Close(); return; - LowTexts[LowTexts.IndexOf(model)] = newLowTest; + } + newModel.I18nResource.CopyDataTo(ModInfoModel.Current.I18nResource, true); + newModel.I18nResource = ModInfoModel.Current.I18nResource; + LowTexts[LowTexts.IndexOf(model)] = newModel; + model.Close(); } private void RemoveCommand_ExecuteCommand(LowTextModel model) @@ -90,5 +103,6 @@ public class LowTextPageVM : ObservableObjectX if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No) return; LowTexts.Remove(model); + model.Close(); } } diff --git a/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs index ecd2bfb..d21dd64 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs @@ -160,8 +160,8 @@ public class ModEditWindowVM : ObservableObjectX window.ShowDialog(); if (window.IsCancel) return; - ModInfoModel.Current.I18nResource.AddCulture(window.ViewModel.Culture); - ModInfoModel.Current.I18nResource.SetCurrentCulture(window.ViewModel.Culture); + I18nResource.AddCulture(window.ViewModel.Culture); + I18nResource.SetCurrentCulture(window.ViewModel.Culture); } /// @@ -175,7 +175,7 @@ public class ModEditWindowVM : ObservableObjectX window.ShowDialog(); if (window.IsCancel) return; - ModInfoModel.Current.I18nResource.ReplaceCulture(oldCulture, window.ViewModel.Culture); + I18nResource.ReplaceCulture(oldCulture, window.ViewModel.Culture); } /// @@ -192,7 +192,7 @@ public class ModEditWindowVM : ObservableObjectX ) is MessageBoxResult.No ) return; - ModInfoModel.Current.I18nResource.RemoveCulture(oldCulture); + I18nResource.RemoveCulture(oldCulture); } public void SetMainCultureCommand_ExecuteCommand(string culture) @@ -207,31 +207,11 @@ public class ModEditWindowVM : ObservableObjectX is not MessageBoxResult.Yes ) return; - // TODO - //ModInfo.I18nDatas[culture].Name = ModInfo.ID; - //ModInfo.I18nDatas[culture].Description = ModInfo.DescriptionID; - //foreach (var food in ModInfo.Foods) - //{ - // food.I18nDatas[culture].Name = food.ID; - // food.I18nDatas[culture].Description = food.DescriptionID; - //} - //foreach (var text in ModInfo.LowTexts) - // text.I18nDatas[culture].Text = text.ID; - //foreach (var text in ModInfo.ClickTexts) - // text.I18nDatas[culture].Text = text.ID; - //foreach (var text in ModInfo.SelectTexts) - //{ - // text.I18nDatas[culture].Text = text.ID; - // text.I18nDatas[culture].Choose = text.ChooseID; - //} - //foreach (var pet in ModInfo.Pets) - //{ - // pet.I18nDatas[culture].Name = pet.ID; - // pet.I18nDatas[culture].PetName = pet.PetNameID; - // pet.I18nDatas[culture].Description = pet.DescriptionID; - // foreach (var work in pet.Works) - // work.I18nDatas[culture].Name = work.ID; - //} + foreach (var datas in I18nResource.CultureDatas) + { + I18nResource.SetCurrentCultureData(datas.Key, datas.Key); + } + ModInfo.RefreshAllID(); } #endregion @@ -299,7 +279,7 @@ public class ModEditWindowVM : ObservableObjectX /// 成功为 失败为 private bool ValidationData(ModInfoModel model) { - if (ModInfoModel.Current.I18nResource.CultureDatas.HasValue() is false) + if (I18nResource.CultureDatas.HasValue() is false) { MessageBox.Show( ModEditWindow, diff --git a/VPet.ModMaker/ViewModels/ModEdit/MoveEdit/MovePageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/MoveEdit/MovePageVM.cs index 0ce1f5d..2ef7542 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/MoveEdit/MovePageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/MoveEdit/MovePageVM.cs @@ -24,7 +24,9 @@ public class MovePageVM : ObservableObjectX Filter = f => f.Graph.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; - PropertyChanged += MovePageVM_PropertyChanged; + + PropertyChangedX += MovePageVM_PropertyChangedX; + ; if (Pets.HasValue()) CurrentPet = Pets.FirstOrDefault( m => m.FromMain is false && m.Moves.HasValue(), @@ -78,12 +80,18 @@ public class MovePageVM : ObservableObjectX public ObservableCommand EditCommand { get; } = new(); public ObservableCommand RemoveCommand { get; } = new(); #endregion - private void MovePageVM_PropertyChanged(object? sender, PropertyChangedEventArgs e) + + private void MovePageVM_PropertyChangedX(object? sender, PropertyChangedXEventArgs e) { if (e.PropertyName == nameof(CurrentPet)) { Moves.Clear(); + if (e.OldValue is PetModel pet) + Moves.BindingList(pet.Moves, true); + if (e.NewValue is null) + return; Moves.AddRange(CurrentPet.Moves); + Moves.BindingList(CurrentPet.Moves); } else if (e.PropertyName == nameof(Search)) { diff --git a/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetEditWindowVM.cs index 57bfa99..3e8483c 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetEditWindowVM.cs @@ -31,7 +31,7 @@ public class PetEditWindowVM : ObservableObjectX #region Pet [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private PetModel _pet = new(); + private PetModel _pet = new() { I18nResource = ModInfoModel.Current.I18nResource }; public PetModel Pet { diff --git a/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetPageVM.cs index 10a865b..fc5bbfc 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/PetEdit/PetPageVM.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using HKW.HKWUtils.Extensions; using HKW.HKWUtils.Observable; using LinePutScript.Localization.WPF; using VPet.ModMaker.Models; @@ -23,6 +24,7 @@ public class PetPageVM : ObservableObjectX Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; + Pets.BindingList(ModInfoModel.Current.Pets); AddCommand.ExecuteCommand += AddCommand_ExecuteCommand; EditCommand.ExecuteCommand += EditCommand_ExecuteCommand; @@ -89,21 +91,32 @@ public class PetPageVM : ObservableObjectX var window = new PetEditWindow(); var vm = window.ViewModel; vm.OldPet = model; - var newPet = vm.Pet = new(model); + var newModel = vm.Pet = new(model) { I18nResource = ModInfoModel.Current.TempI18nResource }; + model.I18nResource.CopyDataTo( + newModel.I18nResource, + [model.ID, model.PetNameID, model.DescriptionID], + true + ); window.ShowDialog(); if (window.IsCancel) + { + newModel.I18nResource.ClearCultureData(); + newModel.CloseI18nResource(); return; + } + newModel.I18nResource.CopyDataTo(ModInfoModel.Current.I18nResource, true); + newModel.I18nResource = ModInfoModel.Current.I18nResource; if (model.FromMain) { var index = Pets.IndexOf(model); Pets.Remove(model); - Pets.Insert(index, newPet); + Pets.Insert(index, newModel); } else { - Pets[Pets.IndexOf(model)] = newPet; + Pets[Pets.IndexOf(model)] = newModel; } - model.Close(); + model.CloseI18nResource(); } private void RemoveCommand_ExecuteCommand(PetModel model) @@ -116,5 +129,6 @@ public class PetPageVM : ObservableObjectX if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No) return; Pets.Remove(model); + model.CloseI18nResource(); } } diff --git a/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextEditWindowVM.cs index 2190f45..3574c13 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextEditWindowVM.cs @@ -20,7 +20,8 @@ public class SelectTextEditWindowVM : ObservableObjectX #region SelectText [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private SelectTextModel _selectText = new(); + private SelectTextModel _selectText = + new() { I18nResource = ModInfoModel.Current.I18nResource }; public SelectTextModel SelectText { diff --git a/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextPageVM.cs index 876c8a8..3222641 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/SelectTextEdit/SelectTextPageVM.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using HKW.HKWUtils.Extensions; using HKW.HKWUtils.Observable; using LinePutScript.Localization.WPF; using VPet.ModMaker.Models; @@ -23,6 +24,8 @@ public class SelectTextPageVM : ObservableObjectX Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; + SelectTexts.BindingList(ModInfoModel.Current.SelectTexts); + AddCommand.ExecuteCommand += AddCommand_ExecuteCommand; EditCommand.ExecuteCommand += EditCommand_ExecuteCommand; RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteCommand; @@ -77,11 +80,22 @@ public class SelectTextPageVM : ObservableObjectX var window = new SelectTextEditWindow(); var vm = window.ViewModel; vm.OldSelectText = model; - var newSelectText = vm.SelectText = new(model); + var newModel = vm.SelectText = new(model) + { + I18nResource = ModInfoModel.Current.I18nResource + }; + model.I18nResource.CopyDataTo(newModel.I18nResource, [model.ID, model.ChooseID], true); window.ShowDialog(); if (window.IsCancel) + { + newModel.I18nResource.ClearCultureData(); + newModel.Close(); return; - SelectTexts[SelectTexts.IndexOf(model)] = newSelectText; + } + newModel.I18nResource.CopyDataTo(ModInfoModel.Current.I18nResource, true); + newModel.I18nResource = ModInfoModel.Current.I18nResource; + SelectTexts[SelectTexts.IndexOf(model)] = newModel; + model.Close(); } private void RemoveCommand_ExecuteCommand(SelectTextModel model) @@ -89,5 +103,6 @@ public class SelectTextPageVM : ObservableObjectX if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No) return; SelectTexts.Remove(model); + model.Close(); } } diff --git a/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkEditWindowVM.cs index 20cdd21..a6aecd7 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkEditWindowVM.cs @@ -102,7 +102,7 @@ public class WorkEditWindowVM : ObservableObjectX #region Work [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private WorkModel _work = new(); + private WorkModel _work = new() { I18nResource = ModInfoModel.Current.I18nResource }; public WorkModel Work { diff --git a/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkPageVM.cs index ba28c70..9bcd391 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/WorkEdit/WorkPageVM.cs @@ -24,7 +24,8 @@ public class WorkPageVM : ObservableObjectX Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase), FilteredList = new() }; - PropertyChanged += WorkPageVM_PropertyChanged; + PropertyChangedX += WorkPageVM_PropertyChangedX; + if (Pets.HasValue()) CurrentPet = Pets.FirstOrDefault( m => m.FromMain is false && m.Works.HasValue(), @@ -40,7 +41,7 @@ public class WorkPageVM : ObservableObjectX #region Property #region Works [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private ObservableFilterList> _works; + private ObservableFilterList> _works = null!; public ObservableFilterList> Works { @@ -53,7 +54,7 @@ public class WorkPageVM : ObservableObjectX #region CurrentPet [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private PetModel _currentPet; + private PetModel _currentPet = null!; public PetModel CurrentPet { @@ -78,12 +79,18 @@ public class WorkPageVM : ObservableObjectX public ObservableCommand EditCommand { get; } = new(); public ObservableCommand RemoveCommand { get; } = new(); #endregion - private void WorkPageVM_PropertyChanged(object? sender, PropertyChangedEventArgs e) + + private void WorkPageVM_PropertyChangedX(object? sender, PropertyChangedXEventArgs e) { if (e.PropertyName == nameof(CurrentPet)) { Works.Clear(); + if (e.OldValue is PetModel pet) + Works.BindingList(pet.Works, true); + if (e.NewValue is null) + return; Works.AddRange(CurrentPet.Works); + Works.BindingList(CurrentPet.Works); } else if (e.PropertyName == nameof(Search)) { @@ -108,11 +115,21 @@ public class WorkPageVM : ObservableObjectX var vm = window.ViewModel; vm.CurrentPet = CurrentPet; vm.OldWork = model; - var newWork = vm.Work = new(model); + var newModel = vm.Work = new(model) + { + I18nResource = ModInfoModel.Current.TempI18nResource + }; + model.I18nResource.CopyDataTo(newModel.I18nResource, model.ID, true); window.ShowDialog(); if (window.IsCancel) + { + newModel.I18nResource.ClearCultureData(); + newModel.Close(); return; - Works[Works.IndexOf(model)] = newWork; + } + newModel.I18nResource.CopyDataTo(ModInfoModel.Current.I18nResource, true); + newModel.I18nResource = ModInfoModel.Current.I18nResource; + Works[Works.IndexOf(model)] = newModel; model.Close(); } diff --git a/VPet.ModMaker/Views/ModEdit/AddCultureWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/AddCultureWindow.xaml.cs index 06a5c75..3215c60 100644 --- a/VPet.ModMaker/Views/ModEdit/AddCultureWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/AddCultureWindow.xaml.cs @@ -79,7 +79,7 @@ public partial class AddCultureWindow : WindowX if ( MessageBoxX.Show( this, - "无法正确打开链接,需要复制自行访问吗", + "无法打开链接,需要复制自行访问吗", "", MessageBoxButton.YesNo, MessageBoxIcon.Warning diff --git a/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimeEditWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimeEditWindow.xaml.cs index 876c8dd..3b03170 100644 --- a/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimeEditWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimeEditWindow.xaml.cs @@ -27,8 +27,8 @@ public partial class AnimeEditWindow : Window { public AnimeEditWindow() { - DataContext = new AnimeEditWindowVM(); InitializeComponent(); + DataContext = new AnimeEditWindowVM(); Closed += (s, e) => { try @@ -77,12 +77,12 @@ public partial class AnimeEditWindow : Window RoutedEvent = MouseWheelEvent, Source = sender }; - var parent = ((Control)sender).Parent as UIElement; + var parent = ((Control)sender!).Parent as UIElement; parent.RaiseEvent(eventArg); e.Handled = true; } - private object _dropSender; + private object _dropSender = null!; private void ListBox_PreviewMouseMove(object? sender, MouseEventArgs e) { diff --git a/VPet.ModMaker/Views/ModEdit/AnimeEdit/FoodAnimeEditWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/AnimeEdit/FoodAnimeEditWindow.xaml.cs index d09ac75..919ceab 100644 --- a/VPet.ModMaker/Views/ModEdit/AnimeEdit/FoodAnimeEditWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/AnimeEdit/FoodAnimeEditWindow.xaml.cs @@ -28,8 +28,8 @@ public partial class FoodAnimeEditWindow : Window { public FoodAnimeEditWindow() { - DataContext = new FoodAnimeEditWindowVM(); InitializeComponent(); + DataContext = new FoodAnimeEditWindowVM(); Closed += (s, e) => { try diff --git a/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml b/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml index 2314557..f75cb6e 100644 --- a/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml +++ b/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml @@ -43,6 +43,7 @@ CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" + CellEditEnding="DataGrid_Datas_CellEditEnding" ItemsSource="{Binding I18nDatas.FilteredList}" ScrollViewer.IsDeferredScrollingEnabled="True" VirtualizingStackPanel.VirtualizationMode="Recycling"> diff --git a/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml.cs index d23ab16..6e0a850 100644 --- a/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/I18nEditWindow.xaml.cs @@ -87,8 +87,6 @@ public partial class I18nEditWindow : WindowX /// public void ReplaceCulture(string oldCultureName, string newCultureName) { - //if (_dataGridI18nColumns.ContainsKey(newCultureName)) - // throw new(); var column = _dataGridI18nColumns[oldCultureName]; column.Header = newCultureName; _dataGridI18nColumns.Remove(oldCultureName); @@ -111,4 +109,9 @@ public partial class I18nEditWindow : WindowX } #endregion + + private void DataGrid_Datas_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) + { + ViewModel.CellEdit = true; + } } diff --git a/VPet.ModMaker/Views/ModEdit/ModEditWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/ModEditWindow.xaml.cs index 672db18..17926c7 100644 --- a/VPet.ModMaker/Views/ModEdit/ModEditWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/ModEditWindow.xaml.cs @@ -76,7 +76,7 @@ public partial class ModEditWindow : WindowX /// public void InitializeData() { - if (ModInfoModel.Current.I18nResource.CultureDatas.HasValue() is false) + if (ModInfoModel.Current.I18nResource.Cultures.HasValue() is false) { if ( MessageBox.Show("未添加任何文化,确定要添加文化吗?".Translate(), "", MessageBoxButton.YesNo) @@ -84,8 +84,10 @@ public partial class ModEditWindow : WindowX ) return; ViewModel.AddCultureCommand_ExecuteCommand(); + if (string.IsNullOrWhiteSpace(ViewModel.ModInfo.ID)) + return; if ( - ModInfoModel.Current.I18nResource.CultureDatas.HasValue() is false + ModInfoModel.Current.I18nResource.Cultures.HasValue() is false || MessageBox.Show( "需要将文化 {0} 设为主要文化吗?".Translate( ModInfoModel.Current.I18nResource.Cultures.First().Name diff --git a/VPet.ModMaker/Views/ModEdit/PetEdit/PetEditWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/PetEdit/PetEditWindow.xaml.cs index 4cb69d1..57696ff 100644 --- a/VPet.ModMaker/Views/ModEdit/PetEdit/PetEditWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/PetEdit/PetEditWindow.xaml.cs @@ -27,8 +27,8 @@ public partial class PetEditWindow : Window public PetEditWindow() { - DataContext = new PetEditWindowVM(); InitializeComponent(); + DataContext = new PetEditWindowVM(); Closed += (s, e) => { ViewModel.Close(); diff --git a/VPet.ModMaker/Views/ModEdit/WorkEdit/WorkEditWindow.xaml.cs b/VPet.ModMaker/Views/ModEdit/WorkEdit/WorkEditWindow.xaml.cs index 61d0a03..f366c00 100644 --- a/VPet.ModMaker/Views/ModEdit/WorkEdit/WorkEditWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModEdit/WorkEdit/WorkEditWindow.xaml.cs @@ -28,10 +28,7 @@ public partial class WorkEditWindow : Window public WorkEditWindow() { InitializeComponent(); - this.SetDataContext(() => { - //TODO - //ViewModel.Close(); - }); + this.SetDataContext(); } private void Button_Cancel_Click(object? sender, RoutedEventArgs e) @@ -41,15 +38,15 @@ public partial class WorkEditWindow : Window private void Button_Yes_Click(object? sender, RoutedEventArgs e) { - if (string.IsNullOrEmpty(ViewModel.Work.ID)) + if (string.IsNullOrWhiteSpace(ViewModel.Work.ID)) { - MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning); + MessageBox.Show("ID不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning); return; } - if (string.IsNullOrEmpty(ViewModel.Work.Graph)) + if (string.IsNullOrWhiteSpace(ViewModel.Work.Graph)) { MessageBox.Show( - "指定动画Id不可为空".Translate(), + "指定动画ID不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning @@ -61,7 +58,7 @@ public partial class WorkEditWindow : Window && ViewModel.CurrentPet.Works.Any(i => i.ID == ViewModel.Work.ID) ) { - MessageBox.Show("此Id已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning); + MessageBox.Show("此ID已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning); return; } IsCancel = false; diff --git a/VPet.ModMaker/Views/ModMakerWindow.xaml.cs b/VPet.ModMaker/Views/ModMakerWindow.xaml.cs index cd7c0fb..ee80224 100644 --- a/VPet.ModMaker/Views/ModMakerWindow.xaml.cs +++ b/VPet.ModMaker/Views/ModMakerWindow.xaml.cs @@ -84,7 +84,7 @@ public partial class ModMakerWindow : WindowX if ( MessageBoxX.Show( this, - "无法正确打开链接,需要复制自行访问吗".Translate(), + "无法打开链接,需要复制自行访问吗".Translate(), "", MessageBoxButton.YesNo, MessageBoxIcon.Warning