mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
更新:
- 保存宠物时, 若本体存在同名宠物, 则只会保存差异数据 修复: - 模组宠物和本体宠物同时出现的问题
This commit is contained in:
parent
fb81811be0
commit
9546fb604a
@ -9,6 +9,7 @@
|
|||||||
<c:BrushToMediaColorConverter x:Key="BrushToMediaColorConverter" />
|
<c:BrushToMediaColorConverter x:Key="BrushToMediaColorConverter" />
|
||||||
<c:MaxConverter x:Key="MaxConverter" />
|
<c:MaxConverter x:Key="MaxConverter" />
|
||||||
<c:FalseToHiddenConverter x:Key="FalseToHiddenConverter" />
|
<c:FalseToHiddenConverter x:Key="FalseToHiddenConverter" />
|
||||||
|
<c:FalseToCollapsedConverter x:Key="FalseToCollapsedConverter" />
|
||||||
<c:EqualsConverter x:Key="EqualsConverter" />
|
<c:EqualsConverter x:Key="EqualsConverter" />
|
||||||
<c:NotEqualsConverter x:Key="NotEqualsConverter" />
|
<c:NotEqualsConverter x:Key="NotEqualsConverter" />
|
||||||
<c:NullToFalseConverter x:Key="NullToFalseConverter" />
|
<c:NullToFalseConverter x:Key="NullToFalseConverter" />
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using HKW.Models;
|
using LinePutScript;
|
||||||
using LinePutScript;
|
|
||||||
using LinePutScript.Converter;
|
using LinePutScript.Converter;
|
||||||
using LinePutScript.Dictionary;
|
using LinePutScript.Dictionary;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using HKW.Models;
|
using LinePutScript.Converter;
|
||||||
using LinePutScript.Converter;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -9,7 +9,6 @@ using System.Windows.Controls;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using VPet_Simulator.Windows.Interface;
|
using VPet_Simulator.Windows.Interface;
|
||||||
using VPet.ModMaker.Views;
|
using VPet.ModMaker.Views;
|
||||||
using HKW.Models;
|
|
||||||
|
|
||||||
namespace VPet.ModMaker.Models;
|
namespace VPet.ModMaker.Models;
|
||||||
|
|
||||||
@ -51,12 +50,7 @@ public class ModMaker : MainPlugin
|
|||||||
ModMakerInfo.GameVersion = MW.version;
|
ModMakerInfo.GameVersion = MW.version;
|
||||||
// 载入本体宠物
|
// 载入本体宠物
|
||||||
foreach (var pet in MW.Pets)
|
foreach (var pet in MW.Pets)
|
||||||
{
|
ModMakerInfo.MainPets.Add(pet.Name, new(pet, true));
|
||||||
var petModel = new PetModel();
|
|
||||||
petModel.SourceId = pet.Name;
|
|
||||||
petModel.Id.Value = pet.Name + " (来自本体)".Translate();
|
|
||||||
ModMakerInfo.Pets.Add(petModel);
|
|
||||||
}
|
|
||||||
//Maker.ModMaker = this;
|
//Maker.ModMaker = this;
|
||||||
Maker.Show();
|
Maker.Show();
|
||||||
Maker.Closed += Maker_Closed;
|
Maker.Closed += Maker_Closed;
|
||||||
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VPet.ModMaker.Models.ModModel;
|
using VPet.ModMaker.Models.ModModel;
|
||||||
|
using VPet_Simulator.Core;
|
||||||
|
|
||||||
namespace VPet.ModMaker.Models;
|
namespace VPet.ModMaker.Models;
|
||||||
|
|
||||||
@ -34,11 +35,24 @@ public static class ModMakerInfo
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本体的宠物
|
/// 本体的宠物
|
||||||
|
/// <para>
|
||||||
|
/// (PetId, PetModel)
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<PetModel> Pets { get; } = new();
|
public static Dictionary<string, PetModel> MainPets { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本地风格
|
/// 本地风格
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static NativeStyles NativeStyles { get; } = new();
|
public static NativeStyles NativeStyles { get; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是含有名称的动画
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="graphType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool IsHasNameAnime(this GraphInfo.GraphType graphType)
|
||||||
|
{
|
||||||
|
return AnimeTypeModel.HasNameAnimes.Contains(graphType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils;
|
||||||
using HKW.Models;
|
using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
using LinePutScript.Converter;
|
using LinePutScript.Converter;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -145,14 +146,14 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
|||||||
Working.Value = clickText.Working;
|
Working.Value = clickText.Working;
|
||||||
WorkingState.Value = clickText.State;
|
WorkingState.Value = clickText.State;
|
||||||
DayTime.EnumValue.Value = clickText.DaiTime;
|
DayTime.EnumValue.Value = clickText.DaiTime;
|
||||||
Like.SetValue(clickText.LikeMin, clickText.LikeMax);
|
Like = new(clickText.LikeMin, clickText.LikeMax);
|
||||||
Health.SetValue(clickText.HealthMin, clickText.HealthMax);
|
Health = new(clickText.HealthMin, clickText.HealthMax);
|
||||||
Level.SetValue(clickText.LevelMin, clickText.LevelMax);
|
Level = new(clickText.LevelMin, clickText.LevelMax);
|
||||||
Money.SetValue(clickText.MoneyMin, clickText.MoneyMax);
|
Money = new(clickText.MoneyMin, clickText.MoneyMax);
|
||||||
Food.SetValue(clickText.FoodMin, clickText.FoodMax);
|
Food = new(clickText.FoodMin, clickText.FoodMax);
|
||||||
Drink.SetValue(clickText.DrinkMin, clickText.DrinkMax);
|
Drink = new(clickText.DrinkMin, clickText.DrinkMax);
|
||||||
Feel.SetValue(clickText.FeelMin, clickText.FeelMax);
|
Feel = new(clickText.FeelMin, clickText.FeelMax);
|
||||||
Strength.SetValue(clickText.StrengthMin, clickText.StrengthMax);
|
Strength = new(clickText.StrengthMin, clickText.StrengthMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClickText ToClickText()
|
public ClickText ToClickText()
|
||||||
@ -164,22 +165,22 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
|||||||
Working = Working.Value,
|
Working = Working.Value,
|
||||||
State = WorkingState.Value,
|
State = WorkingState.Value,
|
||||||
DaiTime = DayTime.EnumValue.Value,
|
DaiTime = DayTime.EnumValue.Value,
|
||||||
LikeMax = Like.Max.Value,
|
LikeMax = Like.Max,
|
||||||
LikeMin = Like.Min.Value,
|
LikeMin = Like.Min,
|
||||||
HealthMin = Health.Min.Value,
|
HealthMin = Health.Min,
|
||||||
HealthMax = Health.Max.Value,
|
HealthMax = Health.Max,
|
||||||
LevelMin = Level.Min.Value,
|
LevelMin = Level.Min,
|
||||||
LevelMax = Level.Max.Value,
|
LevelMax = Level.Max,
|
||||||
MoneyMin = Money.Min.Value,
|
MoneyMin = Money.Min,
|
||||||
MoneyMax = Money.Max.Value,
|
MoneyMax = Money.Max,
|
||||||
FoodMin = Food.Min.Value,
|
FoodMin = Food.Min,
|
||||||
FoodMax = Food.Max.Value,
|
FoodMax = Food.Max,
|
||||||
DrinkMin = Drink.Min.Value,
|
DrinkMin = Drink.Min,
|
||||||
DrinkMax = Drink.Max.Value,
|
DrinkMax = Drink.Max,
|
||||||
FeelMin = Feel.Min.Value,
|
FeelMin = Feel.Min,
|
||||||
FeelMax = Feel.Max.Value,
|
FeelMax = Feel.Max,
|
||||||
StrengthMin = Strength.Min.Value,
|
StrengthMin = Strength.Min,
|
||||||
StrengthMax = Strength.Max.Value,
|
StrengthMax = Strength.Max,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class FoodAnimeModel
|
|||||||
foodLocationInfo.Duration.Value = int.Parse(infos[0]);
|
foodLocationInfo.Duration.Value = int.Parse(infos[0]);
|
||||||
if (infos.Length > 1)
|
if (infos.Length > 1)
|
||||||
{
|
{
|
||||||
foodLocationInfo.Rect.SetValue(
|
foodLocationInfo.Rect = new(
|
||||||
double.Parse(infos[1]),
|
double.Parse(infos[1]),
|
||||||
double.Parse(infos[2]),
|
double.Parse(infos[2]),
|
||||||
double.Parse(infos[3]),
|
double.Parse(infos[3]),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript;
|
using LinePutScript;
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
|
@ -20,7 +20,7 @@ public class FoodLocationModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 范围
|
/// 范围
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ObservableRect<double> Rect { get; } = new();
|
public ObservableRect<double> Rect { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 旋转角度
|
/// 旋转角度
|
||||||
@ -34,9 +34,9 @@ public class FoodLocationModel
|
|||||||
|
|
||||||
public FoodLocationModel()
|
public FoodLocationModel()
|
||||||
{
|
{
|
||||||
Rect.Width.ValueChanged += (s, e) =>
|
Rect.PropertyChangedX += (s, e) =>
|
||||||
{
|
{
|
||||||
Rect.Height.Value = e.NewValue;
|
Rect.Height = (int)e.NewValue;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ public class FoodLocationModel
|
|||||||
{
|
{
|
||||||
var model = new FoodLocationModel();
|
var model = new FoodLocationModel();
|
||||||
model.Duration.Value = Duration.Value;
|
model.Duration.Value = Duration.Value;
|
||||||
model.Rect.SetValue(Rect.X.Value, Rect.Y.Value, Rect.Width.Value, Rect.Height.Value);
|
model.Rect = new(Rect.X, Rect.Y, Rect.Width, Rect.Height);
|
||||||
model.Rotate.Value = Rotate.Value;
|
model.Rotate.Value = Rotate.Value;
|
||||||
model.Opacity.Value = Opacity.Value;
|
model.Opacity.Value = Opacity.Value;
|
||||||
return model;
|
return model;
|
||||||
@ -52,6 +52,6 @@ public class FoodLocationModel
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{Duration.Value},{Rect.X.Value},{Rect.Y.Value},{Rect.Width.Value},{Rotate.Value},{Opacity.Value}";
|
return $"{Duration.Value}, {Rect.X}, {Rect.Y}, {Rect.Width}, {Rotate.Value}, {Opacity.Value}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript;
|
using LinePutScript;
|
||||||
using LinePutScript.Converter;
|
using LinePutScript.Converter;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils;
|
||||||
using HKW.Models;
|
using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils;
|
||||||
using HKW.Models;
|
using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
using LinePutScript;
|
using LinePutScript;
|
||||||
using LinePutScript.Converter;
|
using LinePutScript.Converter;
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
@ -20,6 +21,7 @@ using VPet_Simulator.Windows.Interface;
|
|||||||
|
|
||||||
namespace VPet.ModMaker.Models;
|
namespace VPet.ModMaker.Models;
|
||||||
|
|
||||||
|
// TODO: 本体模组显示开关
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 模组信息模型
|
/// 模组信息模型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -142,6 +144,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
foreach (var selectText in loader.SelectTexts)
|
foreach (var selectText in loader.SelectTexts)
|
||||||
SelectTexts.Add(new(selectText));
|
SelectTexts.Add(new(selectText));
|
||||||
|
|
||||||
|
// 载入模组宠物
|
||||||
foreach (var pet in loader.Pets)
|
foreach (var pet in loader.Pets)
|
||||||
{
|
{
|
||||||
var petModel = new PetModel(pet);
|
var petModel = new PetModel(pet);
|
||||||
@ -149,14 +152,16 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
foreach (var p in pet.path)
|
foreach (var p in pet.path)
|
||||||
LoadAnime(petModel, p);
|
LoadAnime(petModel, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入本体宠物
|
// 插入本体宠物
|
||||||
foreach (var pet in ModMakerInfo.Pets)
|
foreach (var pet in ModMakerInfo.MainPets)
|
||||||
{
|
{
|
||||||
// 确保Id不重复
|
// 确保Id不重复
|
||||||
if (Pets.All(i => i.Id.Value != pet.SourceId))
|
if (Pets.All(i => i.Id.Value != pet.Key))
|
||||||
Pets.Insert(0, pet);
|
Pets.Insert(0, pet.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 载入本地化
|
||||||
foreach (var lang in loader.I18nDatas)
|
foreach (var lang in loader.I18nDatas)
|
||||||
I18nDatas.Add(lang.Key, lang.Value);
|
I18nDatas.Add(lang.Key, lang.Value);
|
||||||
OtherI18nDatas = loader.OtherI18nDatas;
|
OtherI18nDatas = loader.OtherI18nDatas;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils;
|
||||||
using HKW.Models;
|
using HKW.HKWUtils.Observable;
|
||||||
using LinePutScript;
|
using LinePutScript;
|
||||||
using LinePutScript.Converter;
|
using LinePutScript.Converter;
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
@ -23,9 +23,9 @@ namespace VPet.ModMaker.Models;
|
|||||||
public class PetModel : I18nModel<I18nPetInfoModel>
|
public class PetModel : I18nModel<I18nPetInfoModel>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 显示的Id 若不为空则判断为来自本体的宠物
|
/// 来自本体
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SourceId { get; set; } = null;
|
public ObservableValue<bool> FromMain { get; set; } = new(false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id
|
/// Id
|
||||||
@ -95,8 +95,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
|
|
||||||
public ObservableValue<int> AnimeCount { get; } = new();
|
public ObservableValue<int> AnimeCount { get; } = new();
|
||||||
|
|
||||||
public bool IsSimplePetModel { get; } = false;
|
|
||||||
|
|
||||||
public PetModel()
|
public PetModel()
|
||||||
{
|
{
|
||||||
PetNameId.Value = $"{Id.Value}_{nameof(PetNameId)}";
|
PetNameId.Value = $"{Id.Value}_{nameof(PetNameId)}";
|
||||||
@ -131,68 +129,62 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||||
}
|
}
|
||||||
|
|
||||||
public PetModel(PetLoader loader)
|
public PetModel(PetLoader loader, bool fromMain = false)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
Id.Value = loader.Name;
|
Id.Value = loader.Name;
|
||||||
PetNameId.Value = loader.PetName;
|
PetNameId.Value = loader.PetName;
|
||||||
DescriptionId.Value = loader.Intor;
|
DescriptionId.Value = loader.Intor;
|
||||||
|
|
||||||
TouchHeadRect.Value.SetValue(
|
TouchHeadRect.Value = new(
|
||||||
loader.Config.TouchHeadLocate.X,
|
loader.Config.TouchHeadLocate.X,
|
||||||
loader.Config.TouchHeadLocate.Y,
|
loader.Config.TouchHeadLocate.Y,
|
||||||
loader.Config.TouchHeadSize.Width,
|
loader.Config.TouchHeadSize.Width,
|
||||||
loader.Config.TouchHeadSize.Height
|
loader.Config.TouchHeadSize.Height
|
||||||
);
|
);
|
||||||
|
|
||||||
TouchBodyRect.Value.SetValue(
|
TouchBodyRect.Value = new(
|
||||||
loader.Config.TouchBodyLocate.X,
|
loader.Config.TouchBodyLocate.X,
|
||||||
loader.Config.TouchBodyLocate.Y,
|
loader.Config.TouchBodyLocate.Y,
|
||||||
loader.Config.TouchBodySize.Width,
|
loader.Config.TouchBodySize.Width,
|
||||||
loader.Config.TouchBodySize.Height
|
loader.Config.TouchBodySize.Height
|
||||||
);
|
);
|
||||||
|
|
||||||
TouchRaisedRect.Value.Happy.Value.SetValue(
|
TouchRaisedRect.Value.Happy = new(
|
||||||
loader.Config.TouchRaisedLocate[0].X,
|
loader.Config.TouchRaisedLocate[0].X,
|
||||||
loader.Config.TouchRaisedLocate[0].Y,
|
loader.Config.TouchRaisedLocate[0].Y,
|
||||||
loader.Config.TouchRaisedSize[0].Width,
|
loader.Config.TouchRaisedSize[0].Width,
|
||||||
loader.Config.TouchRaisedSize[0].Height
|
loader.Config.TouchRaisedSize[0].Height
|
||||||
);
|
);
|
||||||
TouchRaisedRect.Value.Nomal.Value.SetValue(
|
TouchRaisedRect.Value.Nomal = new(
|
||||||
loader.Config.TouchRaisedLocate[1].X,
|
loader.Config.TouchRaisedLocate[1].X,
|
||||||
loader.Config.TouchRaisedLocate[1].Y,
|
loader.Config.TouchRaisedLocate[1].Y,
|
||||||
loader.Config.TouchRaisedSize[1].Width,
|
loader.Config.TouchRaisedSize[1].Width,
|
||||||
loader.Config.TouchRaisedSize[1].Height
|
loader.Config.TouchRaisedSize[1].Height
|
||||||
);
|
);
|
||||||
TouchRaisedRect.Value.PoorCondition.Value.SetValue(
|
TouchRaisedRect.Value.PoorCondition = new(
|
||||||
loader.Config.TouchRaisedLocate[2].X,
|
loader.Config.TouchRaisedLocate[2].X,
|
||||||
loader.Config.TouchRaisedLocate[2].Y,
|
loader.Config.TouchRaisedLocate[2].Y,
|
||||||
loader.Config.TouchRaisedSize[2].Width,
|
loader.Config.TouchRaisedSize[2].Width,
|
||||||
loader.Config.TouchRaisedSize[2].Height
|
loader.Config.TouchRaisedSize[2].Height
|
||||||
);
|
);
|
||||||
TouchRaisedRect.Value.Ill.Value.SetValue(
|
TouchRaisedRect.Value.Ill = new(
|
||||||
loader.Config.TouchRaisedLocate[3].X,
|
loader.Config.TouchRaisedLocate[3].X,
|
||||||
loader.Config.TouchRaisedLocate[3].Y,
|
loader.Config.TouchRaisedLocate[3].Y,
|
||||||
loader.Config.TouchRaisedSize[3].Width,
|
loader.Config.TouchRaisedSize[3].Width,
|
||||||
loader.Config.TouchRaisedSize[3].Height
|
loader.Config.TouchRaisedSize[3].Height
|
||||||
);
|
);
|
||||||
|
|
||||||
RaisePoint.Value.Happy.Value.SetValue(
|
RaisePoint.Value.Happy = new(loader.Config.RaisePoint[0].X, loader.Config.RaisePoint[0].Y);
|
||||||
loader.Config.RaisePoint[0].X,
|
RaisePoint.Value.Nomal = new(loader.Config.RaisePoint[1].X, loader.Config.RaisePoint[1].Y);
|
||||||
loader.Config.RaisePoint[0].Y
|
RaisePoint.Value.PoorCondition = new(
|
||||||
);
|
|
||||||
RaisePoint.Value.Nomal.Value.SetValue(
|
|
||||||
loader.Config.RaisePoint[1].X,
|
|
||||||
loader.Config.RaisePoint[1].Y
|
|
||||||
);
|
|
||||||
RaisePoint.Value.PoorCondition.Value.SetValue(
|
|
||||||
loader.Config.RaisePoint[2].X,
|
loader.Config.RaisePoint[2].X,
|
||||||
loader.Config.RaisePoint[2].Y
|
loader.Config.RaisePoint[2].Y
|
||||||
);
|
);
|
||||||
RaisePoint.Value.Ill.Value.SetValue(
|
RaisePoint.Value.Ill = new(loader.Config.RaisePoint[3].X, loader.Config.RaisePoint[3].Y);
|
||||||
loader.Config.RaisePoint[3].X,
|
// 如果这个宠物数据来自本体, 则不载入 Work 和 Move
|
||||||
loader.Config.RaisePoint[3].Y
|
if (FromMain.Value = fromMain)
|
||||||
);
|
return;
|
||||||
|
|
||||||
foreach (var work in loader.Config.Works)
|
foreach (var work in loader.Config.Works)
|
||||||
Works.Add(new(work));
|
Works.Add(new(work));
|
||||||
@ -200,13 +192,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
Moves.Add(new(move));
|
Moves.Add(new(move));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PetModel(PetLoader loader, bool isSimplePet)
|
|
||||||
: this()
|
|
||||||
{
|
|
||||||
Id.Value = loader.Name;
|
|
||||||
IsSimplePetModel = isSimplePet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
foreach (var anime in Animes)
|
foreach (var anime in Animes)
|
||||||
@ -222,13 +207,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
/// <param name="path">路径</param>
|
/// <param name="path">路径</param>
|
||||||
public void Save(string path)
|
public void Save(string path)
|
||||||
{
|
{
|
||||||
if (IsSimplePetModel)
|
|
||||||
{
|
|
||||||
Id.Value = SourceId;
|
|
||||||
SaveSimplePetInfo(path);
|
|
||||||
Id.Value = SourceId + " (来自本体)".Translate();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||||
{
|
{
|
||||||
ModInfoModel.SaveI18nDatas[cultureName].TryAdd(
|
ModInfoModel.SaveI18nDatas[cultureName].TryAdd(
|
||||||
@ -248,7 +226,11 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
if (File.Exists(petFile) is false)
|
if (File.Exists(petFile) is false)
|
||||||
File.Create(petFile).Close();
|
File.Create(petFile).Close();
|
||||||
var lps = new LPS();
|
var lps = new LPS();
|
||||||
SavePetInfo(lps);
|
// 如果本体中存在相同的宠物, 则只保存差异信息
|
||||||
|
if (ModMakerInfo.MainPets.TryGetValue(Id.Value, out var mainPet))
|
||||||
|
SaveDifferentPetInfo(lps, mainPet);
|
||||||
|
else
|
||||||
|
SavePetInfo(lps);
|
||||||
SaveWorksInfo(lps);
|
SaveWorksInfo(lps);
|
||||||
SaveMoveInfo(lps);
|
SaveMoveInfo(lps);
|
||||||
File.WriteAllText(petFile, lps.ToString());
|
File.WriteAllText(petFile, lps.ToString());
|
||||||
@ -257,18 +239,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
SaveAnime(path);
|
SaveAnime(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveSimplePetInfo(string path)
|
|
||||||
{
|
|
||||||
if (Works.Count == 0 && Moves.Count == 0 && Animes.Count == 0)
|
|
||||||
return;
|
|
||||||
var petFile = Path.Combine(path, $"{Id.Value}.lps");
|
|
||||||
var lps = new LPS { new Line("pet", Id.Value) { new Sub("path", Id.Value), } };
|
|
||||||
SaveWorksInfo(lps);
|
|
||||||
SaveMoveInfo(lps);
|
|
||||||
File.WriteAllText(petFile, lps.ToString());
|
|
||||||
SaveAnime(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveAnime(string path)
|
private void SaveAnime(string path)
|
||||||
{
|
{
|
||||||
var petAnimePath = Path.Combine(path, Id.Value);
|
var petAnimePath = Path.Combine(path, Id.Value);
|
||||||
@ -311,12 +281,42 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region SavePetInfo
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存宠物信息
|
/// 保存宠物信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="lps"></param>
|
/// <param name="lps"></param>
|
||||||
/// <param name="pet"></param>
|
|
||||||
private void SavePetInfo(LPS lps)
|
private void SavePetInfo(LPS lps)
|
||||||
|
{
|
||||||
|
SavePetBasicInfo(lps);
|
||||||
|
SavePetTouchHeadInfo(lps);
|
||||||
|
SavePetTouchBodyInfo(lps);
|
||||||
|
SavePetTouchRaisedInfo(lps);
|
||||||
|
SavePetRaisePointInfo(lps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存差异宠物信息
|
||||||
|
/// <para>
|
||||||
|
/// 用于本体存在同名宠物的情况下
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lps"></param>
|
||||||
|
/// <param name="mainPet">本体宠物</param>
|
||||||
|
private void SaveDifferentPetInfo(LPS lps, PetModel mainPet)
|
||||||
|
{
|
||||||
|
SavePetBasicInfo(lps);
|
||||||
|
if (TouchHeadRect != mainPet.TouchHeadRect)
|
||||||
|
SavePetTouchHeadInfo(lps);
|
||||||
|
if (TouchBodyRect != mainPet.TouchBodyRect)
|
||||||
|
SavePetTouchBodyInfo(lps);
|
||||||
|
if (TouchRaisedRect != mainPet.TouchRaisedRect)
|
||||||
|
SavePetTouchRaisedInfo(lps);
|
||||||
|
if (RaisePoint != mainPet.RaisePoint)
|
||||||
|
SavePetRaisePointInfo(lps);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SavePetBasicInfo(LPS lps)
|
||||||
{
|
{
|
||||||
lps.Add(
|
lps.Add(
|
||||||
new Line("pet", Id.Value)
|
new Line("pet", Id.Value)
|
||||||
@ -326,65 +326,82 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
|||||||
new Sub("petname", PetNameId.Value)
|
new Sub("petname", PetNameId.Value)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SavePetTouchHeadInfo(LPS lps)
|
||||||
|
{
|
||||||
lps.Add(
|
lps.Add(
|
||||||
new Line("touchhead")
|
new Line("touchhead")
|
||||||
{
|
{
|
||||||
new Sub("px", TouchHeadRect.Value.X.Value),
|
new Sub("px", TouchHeadRect.Value.X),
|
||||||
new Sub("py", TouchHeadRect.Value.Y.Value),
|
new Sub("py", TouchHeadRect.Value.Y),
|
||||||
new Sub("sw", TouchHeadRect.Value.Width.Value),
|
new Sub("sw", TouchHeadRect.Value.Width),
|
||||||
new Sub("sh", TouchHeadRect.Value.Height.Value),
|
new Sub("sh", TouchHeadRect.Value.Height),
|
||||||
}
|
|
||||||
);
|
|
||||||
lps.Add(
|
|
||||||
new Line("touchbody")
|
|
||||||
{
|
|
||||||
new Sub("px", TouchBodyRect.Value.X.Value),
|
|
||||||
new Sub("py", TouchBodyRect.Value.Y.Value),
|
|
||||||
new Sub("sw", TouchBodyRect.Value.Width.Value),
|
|
||||||
new Sub("sh", TouchBodyRect.Value.Height.Value),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
lps.Add(
|
|
||||||
new Line("touchraised")
|
|
||||||
{
|
|
||||||
new Sub("happy_px", TouchRaisedRect.Value.Happy.Value.X.Value),
|
|
||||||
new Sub("happy_py", TouchRaisedRect.Value.Happy.Value.Y.Value),
|
|
||||||
new Sub("happy_sw", TouchRaisedRect.Value.Happy.Value.Width.Value),
|
|
||||||
new Sub("happy_sh", TouchRaisedRect.Value.Happy.Value.Height.Value),
|
|
||||||
//
|
|
||||||
new Sub("nomal_px", TouchRaisedRect.Value.Nomal.Value.X.Value),
|
|
||||||
new Sub("nomal_py", TouchRaisedRect.Value.Nomal.Value.Y.Value),
|
|
||||||
new Sub("nomal_sw", TouchRaisedRect.Value.Nomal.Value.Width.Value),
|
|
||||||
new Sub("nomal_sh", TouchRaisedRect.Value.Nomal.Value.Height.Value),
|
|
||||||
//
|
|
||||||
new Sub("poorcondition_px", TouchRaisedRect.Value.PoorCondition.Value.X.Value),
|
|
||||||
new Sub("poorcondition_py", TouchRaisedRect.Value.PoorCondition.Value.Y.Value),
|
|
||||||
new Sub("poorcondition_sw", TouchRaisedRect.Value.PoorCondition.Value.Width.Value),
|
|
||||||
new Sub("poorcondition_sh", TouchRaisedRect.Value.PoorCondition.Value.Height.Value),
|
|
||||||
//
|
|
||||||
new Sub("ill_px", TouchRaisedRect.Value.Ill.Value.X.Value),
|
|
||||||
new Sub("ill_py", TouchRaisedRect.Value.Ill.Value.Y.Value),
|
|
||||||
new Sub("ill_sw", TouchRaisedRect.Value.Ill.Value.Width.Value),
|
|
||||||
new Sub("ill_sh", TouchRaisedRect.Value.Ill.Value.Height.Value),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
lps.Add(
|
|
||||||
new Line("raisepoint")
|
|
||||||
{
|
|
||||||
new Sub("happy_x", RaisePoint.Value.Happy.Value.X.Value),
|
|
||||||
new Sub("happy_y", RaisePoint.Value.Happy.Value.Y.Value),
|
|
||||||
//
|
|
||||||
new Sub("nomal_x", RaisePoint.Value.Nomal.Value.X.Value),
|
|
||||||
new Sub("nomal_y", RaisePoint.Value.Nomal.Value.Y.Value),
|
|
||||||
//
|
|
||||||
new Sub("poorcondition_x", RaisePoint.Value.PoorCondition.Value.X.Value),
|
|
||||||
new Sub("poorcondition_y", RaisePoint.Value.PoorCondition.Value.Y.Value),
|
|
||||||
//
|
|
||||||
new Sub("ill_x", RaisePoint.Value.Ill.Value.X.Value),
|
|
||||||
new Sub("ill_y", RaisePoint.Value.Ill.Value.Y.Value),
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SavePetTouchBodyInfo(LPS lps)
|
||||||
|
{
|
||||||
|
lps.Add(
|
||||||
|
new Line("touchbody")
|
||||||
|
{
|
||||||
|
new Sub("px", TouchBodyRect.Value.X),
|
||||||
|
new Sub("py", TouchBodyRect.Value.Y),
|
||||||
|
new Sub("sw", TouchBodyRect.Value.Width),
|
||||||
|
new Sub("sh", TouchBodyRect.Value.Height),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SavePetTouchRaisedInfo(LPS lps)
|
||||||
|
{
|
||||||
|
lps.Add(
|
||||||
|
new Line("touchraised")
|
||||||
|
{
|
||||||
|
new Sub("happy_px", TouchRaisedRect.Value.Happy.X),
|
||||||
|
new Sub("happy_py", TouchRaisedRect.Value.Happy.Y),
|
||||||
|
new Sub("happy_sw", TouchRaisedRect.Value.Happy.Width),
|
||||||
|
new Sub("happy_sh", TouchRaisedRect.Value.Happy.Height),
|
||||||
|
//
|
||||||
|
new Sub("nomal_px", TouchRaisedRect.Value.Nomal.X),
|
||||||
|
new Sub("nomal_py", TouchRaisedRect.Value.Nomal.Y),
|
||||||
|
new Sub("nomal_sw", TouchRaisedRect.Value.Nomal.Width),
|
||||||
|
new Sub("nomal_sh", TouchRaisedRect.Value.Nomal.Height),
|
||||||
|
//
|
||||||
|
new Sub("poorcondition_px", TouchRaisedRect.Value.PoorCondition.X),
|
||||||
|
new Sub("poorcondition_py", TouchRaisedRect.Value.PoorCondition.Y),
|
||||||
|
new Sub("poorcondition_sw", TouchRaisedRect.Value.PoorCondition.Width),
|
||||||
|
new Sub("poorcondition_sh", TouchRaisedRect.Value.PoorCondition.Height),
|
||||||
|
//
|
||||||
|
new Sub("ill_px", TouchRaisedRect.Value.Ill.X),
|
||||||
|
new Sub("ill_py", TouchRaisedRect.Value.Ill.Y),
|
||||||
|
new Sub("ill_sw", TouchRaisedRect.Value.Ill.Width),
|
||||||
|
new Sub("ill_sh", TouchRaisedRect.Value.Ill.Height),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SavePetRaisePointInfo(LPS lps)
|
||||||
|
{
|
||||||
|
lps.Add(
|
||||||
|
new Line("raisepoint")
|
||||||
|
{
|
||||||
|
new Sub("happy_x", RaisePoint.Value.Happy.X),
|
||||||
|
new Sub("happy_y", RaisePoint.Value.Happy.Y),
|
||||||
|
//
|
||||||
|
new Sub("nomal_x", RaisePoint.Value.Nomal.X),
|
||||||
|
new Sub("nomal_y", RaisePoint.Value.Nomal.Y),
|
||||||
|
//
|
||||||
|
new Sub("poorcondition_x", RaisePoint.Value.PoorCondition.X),
|
||||||
|
new Sub("poorcondition_y", RaisePoint.Value.PoorCondition.Y),
|
||||||
|
//
|
||||||
|
new Sub("ill_x", RaisePoint.Value.Ill.X),
|
||||||
|
new Sub("ill_y", RaisePoint.Value.Ill.Y),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,13 +422,41 @@ public class I18nPetInfoModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class ObservableMultiStateRect
|
public class ObservableMultiStateRect
|
||||||
|
: ObservableClass<ObservableMultiStateRect>,
|
||||||
|
IEquatable<ObservableMultiStateRect>
|
||||||
{
|
{
|
||||||
public ObservableValue<ObservableRect<double>> Happy { get; } = new(new());
|
private ObservableRect<double> _happy;
|
||||||
public ObservableValue<ObservableRect<double>> Nomal { get; } = new(new());
|
public ObservableRect<double> Happy
|
||||||
public ObservableValue<ObservableRect<double>> PoorCondition { get; } = new(new());
|
{
|
||||||
public ObservableValue<ObservableRect<double>> Ill { get; } = new(new());
|
get => _happy;
|
||||||
|
set => SetProperty(ref _happy, value);
|
||||||
|
}
|
||||||
|
private ObservableRect<double> _nomal;
|
||||||
|
public ObservableRect<double> Nomal
|
||||||
|
{
|
||||||
|
get => _nomal;
|
||||||
|
set => SetProperty(ref _nomal, value);
|
||||||
|
}
|
||||||
|
private ObservableRect<double> _poorCondition;
|
||||||
|
public ObservableRect<double> PoorCondition
|
||||||
|
{
|
||||||
|
get => _poorCondition;
|
||||||
|
set => SetProperty(ref _poorCondition, value);
|
||||||
|
}
|
||||||
|
private ObservableRect<double> _ill;
|
||||||
|
public ObservableRect<double> Ill
|
||||||
|
{
|
||||||
|
get => _ill;
|
||||||
|
set => SetProperty(ref _ill, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableMultiStateRect() { }
|
public ObservableMultiStateRect()
|
||||||
|
{
|
||||||
|
Happy = new();
|
||||||
|
Nomal = new();
|
||||||
|
PoorCondition = new();
|
||||||
|
Ill = new();
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableMultiStateRect(
|
public ObservableMultiStateRect(
|
||||||
ObservableRect<double> happy,
|
ObservableRect<double> happy,
|
||||||
@ -420,31 +465,101 @@ public class ObservableMultiStateRect
|
|||||||
ObservableRect<double> ill
|
ObservableRect<double> ill
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Happy.Value = happy;
|
Happy = happy;
|
||||||
Nomal.Value = nomal;
|
Nomal = nomal;
|
||||||
PoorCondition.Value = poorCondition;
|
PoorCondition = poorCondition;
|
||||||
Ill.Value = ill;
|
Ill = ill;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableMultiStateRect Copy()
|
public ObservableMultiStateRect Copy()
|
||||||
{
|
{
|
||||||
var result = new ObservableMultiStateRect();
|
return new()
|
||||||
result.Happy.Value = Happy.Value.Copy();
|
{
|
||||||
result.Nomal.Value = Nomal.Value.Copy();
|
Happy = Happy.Copy(),
|
||||||
result.PoorCondition.Value = PoorCondition.Value.Copy();
|
Nomal = Nomal.Copy(),
|
||||||
result.Ill.Value = Ill.Value.Copy();
|
PoorCondition = PoorCondition.Copy(),
|
||||||
return result;
|
Ill = Ill.Copy(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(Happy, Nomal, PoorCondition, Ill);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is ObservableMultiStateRect temp
|
||||||
|
&& EqualityComparer<ObservableRect<double>>.Default.Equals(Happy, temp.Happy)
|
||||||
|
&& EqualityComparer<ObservableRect<double>>.Default.Equals(Nomal, temp.Nomal)
|
||||||
|
&& EqualityComparer<ObservableRect<double>>.Default.Equals(
|
||||||
|
PoorCondition,
|
||||||
|
temp.PoorCondition
|
||||||
|
)
|
||||||
|
&& EqualityComparer<ObservableRect<double>>.Default.Equals(Ill, temp.Ill);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Equals(ObservableMultiStateRect? other)
|
||||||
|
{
|
||||||
|
return Equals(obj: other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator ==(ObservableMultiStateRect a, ObservableMultiStateRect b)
|
||||||
|
{
|
||||||
|
return Equals(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator !=(ObservableMultiStateRect a, ObservableMultiStateRect b)
|
||||||
|
{
|
||||||
|
return Equals(a, b) is not true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObservableMultiStatePoint
|
public class ObservableMultiStatePoint
|
||||||
|
: ObservableClass<ObservableMultiStatePoint>,
|
||||||
|
IEquatable<ObservableMultiStatePoint>
|
||||||
{
|
{
|
||||||
public ObservableValue<ObservablePoint<double>> Happy { get; } = new(new());
|
private ObservablePoint<double> _happy;
|
||||||
public ObservableValue<ObservablePoint<double>> Nomal { get; } = new(new());
|
public ObservablePoint<double> Happy
|
||||||
public ObservableValue<ObservablePoint<double>> PoorCondition { get; } = new(new());
|
{
|
||||||
public ObservableValue<ObservablePoint<double>> Ill { get; } = new(new());
|
get => _happy;
|
||||||
|
set => SetProperty(ref _happy, value);
|
||||||
|
}
|
||||||
|
private ObservablePoint<double> _nomal;
|
||||||
|
public ObservablePoint<double> Nomal
|
||||||
|
{
|
||||||
|
get => _nomal;
|
||||||
|
set => SetProperty(ref _nomal, value);
|
||||||
|
}
|
||||||
|
private ObservablePoint<double> _poorCondition;
|
||||||
|
public ObservablePoint<double> PoorCondition
|
||||||
|
{
|
||||||
|
get => _poorCondition;
|
||||||
|
set => SetProperty(ref _poorCondition, value);
|
||||||
|
}
|
||||||
|
private ObservablePoint<double> _ill;
|
||||||
|
public ObservablePoint<double> Ill
|
||||||
|
{
|
||||||
|
get => _ill;
|
||||||
|
set => SetProperty(ref _ill, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableMultiStatePoint() { }
|
public ObservableMultiStatePoint()
|
||||||
|
{
|
||||||
|
Happy = new();
|
||||||
|
Nomal = new();
|
||||||
|
PoorCondition = new();
|
||||||
|
Ill = new();
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableMultiStatePoint(
|
public ObservableMultiStatePoint(
|
||||||
ObservablePoint<double> happy,
|
ObservablePoint<double> happy,
|
||||||
@ -453,19 +568,61 @@ public class ObservableMultiStatePoint
|
|||||||
ObservablePoint<double> ill
|
ObservablePoint<double> ill
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Happy.Value = happy;
|
Happy = happy;
|
||||||
Nomal.Value = nomal;
|
Nomal = nomal;
|
||||||
PoorCondition.Value = poorCondition;
|
PoorCondition = poorCondition;
|
||||||
Ill.Value = ill;
|
Ill = ill;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableMultiStatePoint Copy()
|
public ObservableMultiStatePoint Copy()
|
||||||
{
|
{
|
||||||
var result = new ObservableMultiStatePoint();
|
return new()
|
||||||
result.Happy.Value = Happy.Value.Copy();
|
{
|
||||||
result.Nomal.Value = Nomal.Value.Copy();
|
Happy = Happy.Copy(),
|
||||||
result.PoorCondition.Value = PoorCondition.Value.Copy();
|
Nomal = Nomal.Copy(),
|
||||||
result.Ill.Value = Ill.Value.Copy();
|
PoorCondition = PoorCondition.Copy(),
|
||||||
return result;
|
Ill = Ill.Copy(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(Happy, Nomal, PoorCondition, Ill);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is ObservableMultiStatePoint temp
|
||||||
|
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(Happy, temp.Happy)
|
||||||
|
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(Nomal, temp.Nomal)
|
||||||
|
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(
|
||||||
|
PoorCondition,
|
||||||
|
temp.PoorCondition
|
||||||
|
)
|
||||||
|
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(Ill, temp.Ill);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Equals(ObservableMultiStatePoint? other)
|
||||||
|
{
|
||||||
|
return Equals(obj: other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator ==(ObservableMultiStatePoint a, ObservableMultiStatePoint b)
|
||||||
|
{
|
||||||
|
return Equals(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator !=(ObservableMultiStatePoint a, ObservableMultiStatePoint b)
|
||||||
|
{
|
||||||
|
return Equals(a, b) is not true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -130,14 +130,14 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
|||||||
Mode.EnumValue.Value = text.Mode;
|
Mode.EnumValue.Value = text.Mode;
|
||||||
Tags.Value = text.Tags is null ? string.Empty : string.Join(", ", text.Tags);
|
Tags.Value = text.Tags is null ? string.Empty : string.Join(", ", text.Tags);
|
||||||
ToTags.Value = text.ToTags is null ? string.Empty : string.Join(", ", text.ToTags);
|
ToTags.Value = text.ToTags is null ? string.Empty : string.Join(", ", text.ToTags);
|
||||||
Like.SetValue(text.LikeMin, text.LikeMax);
|
Like = new(text.LikeMin, text.LikeMax);
|
||||||
Health.SetValue(text.HealthMin, text.HealthMax);
|
Health = new(text.HealthMin, text.HealthMax);
|
||||||
Level.SetValue(text.LevelMin, text.LevelMax);
|
Level = new(text.LevelMin, text.LevelMax);
|
||||||
Money.SetValue(text.MoneyMin, text.MoneyMax);
|
Money = new(text.MoneyMin, text.MoneyMax);
|
||||||
Food.SetValue(text.FoodMin, text.FoodMax);
|
Food = new(text.FoodMin, text.FoodMax);
|
||||||
Drink.SetValue(text.DrinkMin, text.DrinkMax);
|
Drink = new(text.DrinkMin, text.DrinkMax);
|
||||||
Feel.SetValue(text.FeelMin, text.FeelMax);
|
Feel = new(text.FeelMin, text.FeelMax);
|
||||||
Strength.SetValue(text.StrengthMin, text.StrengthMax);
|
Strength = new(text.StrengthMin, text.StrengthMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly static char[] rs_splitChar = { ',', ' ' };
|
private readonly static char[] rs_splitChar = { ',', ' ' };
|
||||||
@ -151,22 +151,22 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
|||||||
Mode = Mode.EnumValue.Value,
|
Mode = Mode.EnumValue.Value,
|
||||||
Tags = new(Tags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
Tags = new(Tags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
||||||
ToTags = new(ToTags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
ToTags = new(ToTags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
||||||
LikeMax = Like.Max.Value,
|
LikeMax = Like.Max,
|
||||||
LikeMin = Like.Min.Value,
|
LikeMin = Like.Min,
|
||||||
HealthMin = Health.Min.Value,
|
HealthMin = Health.Min,
|
||||||
HealthMax = Health.Max.Value,
|
HealthMax = Health.Max,
|
||||||
LevelMin = Level.Min.Value,
|
LevelMin = Level.Min,
|
||||||
LevelMax = Level.Max.Value,
|
LevelMax = Level.Max,
|
||||||
MoneyMin = Money.Min.Value,
|
MoneyMin = Money.Min,
|
||||||
MoneyMax = Money.Max.Value,
|
MoneyMax = Money.Max,
|
||||||
FoodMin = Food.Min.Value,
|
FoodMin = Food.Min,
|
||||||
FoodMax = Food.Max.Value,
|
FoodMax = Food.Max,
|
||||||
DrinkMin = Drink.Min.Value,
|
DrinkMin = Drink.Min,
|
||||||
DrinkMax = Drink.Max.Value,
|
DrinkMax = Drink.Max,
|
||||||
FeelMin = Feel.Min.Value,
|
FeelMin = Feel.Min,
|
||||||
FeelMax = Feel.Max.Value,
|
FeelMax = Feel.Max,
|
||||||
StrengthMin = Strength.Min.Value,
|
StrengthMin = Strength.Min,
|
||||||
StrengthMax = Strength.Max.Value,
|
StrengthMax = Strength.Max,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
//using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
namespace VPet.ModMaker.Models;
|
//namespace VPet.ModMaker.Models;
|
||||||
|
|
||||||
public class ObservablePoint<T>
|
//public class ObservablePoint<T>
|
||||||
{
|
//{
|
||||||
public ObservableValue<T> X { get; } = new();
|
// public ObservableValue<T> X { get; } = new();
|
||||||
public ObservableValue<T> Y { get; } = new();
|
// public ObservableValue<T> Y { get; } = new();
|
||||||
|
|
||||||
public ObservablePoint() { }
|
// public ObservablePoint() { }
|
||||||
|
|
||||||
public ObservablePoint(T x, T y)
|
// public ObservablePoint(T x, T y)
|
||||||
{
|
// {
|
||||||
X.Value = x;
|
// X.Value = x;
|
||||||
Y.Value = y;
|
// Y.Value = y;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void SetValue(T x, T y)
|
// public void SetValue(T x, T y)
|
||||||
{
|
// {
|
||||||
X.Value = x;
|
// X.Value = x;
|
||||||
Y.Value = y;
|
// Y.Value = y;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public ObservablePoint<T> Copy()
|
// public ObservablePoint<T> Copy()
|
||||||
{
|
// {
|
||||||
var result = new ObservablePoint<T>();
|
// var result = new ObservablePoint<T>();
|
||||||
result.X.Value = X.Value;
|
// result.X.Value = X.Value;
|
||||||
result.Y.Value = Y.Value;
|
// result.Y.Value = Y.Value;
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -1,62 +1,62 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
//using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
namespace HKW.Models;
|
//namespace HKW.Models;
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// 可观察的范围
|
///// 可观察的范围
|
||||||
/// </summary>
|
///// </summary>
|
||||||
/// <typeparam name="T">类型</typeparam>
|
///// <typeparam name="T">类型</typeparam>
|
||||||
public class ObservableRange<T>
|
//public class ObservableRange<T>
|
||||||
{
|
//{
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 最小值
|
// /// 最小值
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public ObservableValue<T> Min { get; } = new();
|
// public ObservableValue<T> Min { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 最大值
|
// /// 最大值
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public ObservableValue<T> Max { get; } = new();
|
// public ObservableValue<T> Max { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 信息
|
// /// 信息
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public ObservableValue<string> Info { get; } = new();
|
// public ObservableValue<string> Info { get; } = new();
|
||||||
|
|
||||||
public ObservableRange()
|
// public ObservableRange()
|
||||||
{
|
// {
|
||||||
Min.ValueChanged += ValueChanged;
|
// Min.ValueChanged += ValueChanged;
|
||||||
Max.ValueChanged += ValueChanged;
|
// Max.ValueChanged += ValueChanged;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public ObservableRange(T min, T max)
|
// public ObservableRange(T min, T max)
|
||||||
: this()
|
// : this()
|
||||||
{
|
// {
|
||||||
SetValue(min, max);
|
// SetValue(min, max);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void ValueChanged(ObservableValue<T> sender, ValueChangedEventArgs<T> e)
|
// private void ValueChanged(ObservableValue<T> sender, ValueChangedEventArgs<T> e)
|
||||||
{
|
// {
|
||||||
Info.Value = $"({Min.Value}, {Max.Value})";
|
// Info.Value = $"({Min.Value}, {Max.Value})";
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 设置值
|
// /// 设置值
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="min">最小值</param>
|
// /// <param name="min">最小值</param>
|
||||||
/// <param name="max">最大值</param>
|
// /// <param name="max">最大值</param>
|
||||||
public void SetValue(T min, T max)
|
// public void SetValue(T min, T max)
|
||||||
{
|
// {
|
||||||
Min.Value = min;
|
// Min.Value = min;
|
||||||
Max.Value = max;
|
// Max.Value = max;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 复制
|
// /// 复制
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <returns></returns>
|
// /// <returns></returns>
|
||||||
public ObservableRange<T> Copy()
|
// public ObservableRange<T> Copy()
|
||||||
{
|
// {
|
||||||
return new(Min.Value, Max.Value);
|
// return new(Min.Value, Max.Value);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -1,39 +1,41 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
//using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
namespace VPet.ModMaker.Models;
|
//namespace VPet.ModMaker.Models;
|
||||||
|
|
||||||
public class ObservableRect<T>
|
//public class ObservableRect<T>
|
||||||
{
|
//{
|
||||||
public ObservableValue<T> X { get; } = new();
|
// public ObservableValue<T> X { get; } = new();
|
||||||
public ObservableValue<T> Y { get; } = new();
|
// public ObservableValue<T> Y { get; } = new();
|
||||||
public ObservableValue<T> Width { get; } = new();
|
// public ObservableValue<T> Width { get; } = new();
|
||||||
public ObservableValue<T> Height { get; } = new();
|
// public ObservableValue<T> Height { get; } = new();
|
||||||
|
|
||||||
public ObservableRect() { }
|
// public bool Changed { get; set; } = true;
|
||||||
|
|
||||||
public ObservableRect(T x, T y, T width, T hetght)
|
// public ObservableRect() { }
|
||||||
{
|
|
||||||
X.Value = x;
|
|
||||||
Y.Value = y;
|
|
||||||
Width.Value = width;
|
|
||||||
Height.Value = hetght;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetValue(T x, T y, T width, T hetght)
|
// public ObservableRect(T x, T y, T width, T hetght)
|
||||||
{
|
// {
|
||||||
X.Value = x;
|
// X.Value = x;
|
||||||
Y.Value = y;
|
// Y.Value = y;
|
||||||
Width.Value = width;
|
// Width.Value = width;
|
||||||
Height.Value = hetght;
|
// Height.Value = hetght;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public ObservableRect<T> Copy()
|
// public void SetValue(T x, T y, T width, T hetght)
|
||||||
{
|
// {
|
||||||
var result = new ObservableRect<T>();
|
// X.Value = x;
|
||||||
result.X.Value = X.Value;
|
// Y.Value = y;
|
||||||
result.Y.Value = Y.Value;
|
// Width.Value = width;
|
||||||
result.Width.Value = Width.Value;
|
// Height.Value = hetght;
|
||||||
result.Height.Value = Height.Value;
|
// }
|
||||||
return result;
|
|
||||||
}
|
// public ObservableRect<T> Copy()
|
||||||
}
|
// {
|
||||||
|
// var result = new ObservableRect<T>();
|
||||||
|
// result.X.Value = X.Value;
|
||||||
|
// result.Y.Value = Y.Value;
|
||||||
|
// result.Width.Value = Width.Value;
|
||||||
|
// result.Height.Value = Height.Value;
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通知属性改变后接口
|
||||||
|
/// </summary>
|
||||||
|
public interface INotifyPropertyChangedX<TSender>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通知属性改变后事件
|
||||||
|
/// </summary>
|
||||||
|
public event PropertyChangedXEventHandler<TSender>? PropertyChangedX;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通知属性改变前接口
|
||||||
|
/// </summary>
|
||||||
|
public interface INotifyPropertyChangingX<TSender>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变前事件
|
||||||
|
/// </summary>
|
||||||
|
public event PropertyChangingXEventHandler<TSender>? PropertyChangingX;
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可观察对象
|
||||||
|
/// <para>示例:<code><![CDATA[
|
||||||
|
/// public class ObservableClassExample : ObservableClass<ObservableClassExample>
|
||||||
|
/// {
|
||||||
|
/// int _value = 0;
|
||||||
|
/// public int Value
|
||||||
|
/// {
|
||||||
|
/// get => _value;
|
||||||
|
/// set => SetProperty(ref _value, value);
|
||||||
|
/// }
|
||||||
|
/// }]]></code></para>
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ObservableClass<TObject>
|
||||||
|
: INotifyPropertyChanging,
|
||||||
|
INotifyPropertyChanged,
|
||||||
|
INotifyPropertyChangingX<TObject>,
|
||||||
|
INotifyPropertyChangedX<TObject>
|
||||||
|
where TObject : ObservableClass<TObject>
|
||||||
|
{
|
||||||
|
#region OnPropertyChange
|
||||||
|
/// <summary>
|
||||||
|
/// 设置属性值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">值</param>
|
||||||
|
/// <param name="newValue">新值</param>
|
||||||
|
/// <param name="propertyName">属性名称</param>
|
||||||
|
/// <returns>成功为 <see langword="true"/> 失败为 <see langword="false"/></returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
protected virtual bool SetProperty<TValue>(
|
||||||
|
ref TValue value,
|
||||||
|
TValue newValue,
|
||||||
|
[CallerMemberName] string propertyName = null!
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<TValue>.Default.Equals(value, newValue) is true)
|
||||||
|
return false;
|
||||||
|
var oldValue = value;
|
||||||
|
if (OnPropertyChanging(oldValue, newValue, propertyName))
|
||||||
|
return false;
|
||||||
|
value = newValue;
|
||||||
|
OnPropertyChanged(oldValue, newValue, propertyName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变前
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="oldValue">旧值</param>
|
||||||
|
/// <param name="newValue">新值</param>
|
||||||
|
/// <param name="propertyName">属性名称</param>
|
||||||
|
/// <returns>取消为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
protected virtual bool OnPropertyChanging(
|
||||||
|
object? oldValue,
|
||||||
|
object? newValue,
|
||||||
|
[CallerMemberName] string propertyName = null!
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PropertyChanging?.Invoke(this, new(propertyName));
|
||||||
|
if (PropertyChangingX is null)
|
||||||
|
return false;
|
||||||
|
var e = new PropertyChangingXEventArgs(propertyName, oldValue, newValue);
|
||||||
|
PropertyChangingX?.Invoke((TObject)this, e);
|
||||||
|
if (e.Cancel)
|
||||||
|
PropertyChanged?.Invoke(this, new(propertyName));
|
||||||
|
return e.Cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变后
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="oldValue">旧值</param>
|
||||||
|
/// <param name="newValue">新值</param>
|
||||||
|
/// <param name="propertyName">属性名称</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
protected virtual void OnPropertyChanged(
|
||||||
|
object? oldValue,
|
||||||
|
object? newValue,
|
||||||
|
[CallerMemberName] string propertyName = null!
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new(propertyName));
|
||||||
|
PropertyChangedX?.Invoke((TObject)this, new(propertyName, oldValue, newValue));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Event
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event PropertyChangingEventHandler? PropertyChanging;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event PropertyChangingXEventHandler<TObject>? PropertyChangingX;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event PropertyChangedXEventHandler<TObject>? PropertyChangedX;
|
||||||
|
#endregion
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变后事件参数
|
||||||
|
/// </summary>
|
||||||
|
public class PropertyChangedXEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属性名
|
||||||
|
/// </summary>
|
||||||
|
public string PropertyName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 旧值
|
||||||
|
/// </summary>
|
||||||
|
public object? OldValue { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新值
|
||||||
|
/// </summary>
|
||||||
|
public object? NewValue { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
/// <param name="propertyName">属性名</param>
|
||||||
|
/// <param name="oldValue">旧值</param>
|
||||||
|
/// <param name="newValue">新值</param>
|
||||||
|
public PropertyChangedXEventArgs(string propertyName, object? oldValue, object? newValue)
|
||||||
|
{
|
||||||
|
PropertyName = propertyName;
|
||||||
|
OldValue = oldValue;
|
||||||
|
NewValue = newValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变后事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">发送者</param>
|
||||||
|
/// <param name="e">参数</param>
|
||||||
|
public delegate void PropertyChangedXEventHandler<TSender>(
|
||||||
|
TSender sender,
|
||||||
|
PropertyChangedXEventArgs e
|
||||||
|
);
|
@ -0,0 +1,35 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变前事件参数
|
||||||
|
/// </summary>
|
||||||
|
public class PropertyChangingXEventArgs : CancelEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属性名
|
||||||
|
/// </summary>
|
||||||
|
public string PropertyName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 旧值
|
||||||
|
/// </summary>
|
||||||
|
public object? OldValue { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新值
|
||||||
|
/// </summary>
|
||||||
|
public object? NewValue { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
/// <param name="propertyName">属性名</param>
|
||||||
|
/// <param name="oldValue">旧值</param>
|
||||||
|
/// <param name="newValue">新值</param>
|
||||||
|
public PropertyChangingXEventArgs(string propertyName, object? oldValue, object? newValue)
|
||||||
|
{
|
||||||
|
PropertyName = propertyName;
|
||||||
|
OldValue = oldValue;
|
||||||
|
NewValue = newValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性改变前事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">发送者</param>
|
||||||
|
/// <param name="e">参数</param>
|
||||||
|
public delegate void PropertyChangingXEventHandler<TSender>(
|
||||||
|
TSender sender,
|
||||||
|
PropertyChangingXEventArgs e
|
||||||
|
);
|
@ -7,10 +7,10 @@ namespace HKW.HKWUtils.Observable;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步执行命令事件
|
/// 异步执行命令事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate Task AsyncExecuteEventHandler();
|
public delegate Task ExecuteAsyncEventHandler();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步执行命令事件
|
/// 异步执行命令事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parameter">值</param>
|
/// <param name="parameter">值</param>
|
||||||
public delegate Task AsyncExecuteEventHandler<T>(T parameter);
|
public delegate Task ExecuteAsyncEventHandler<T>(T parameter);
|
@ -10,41 +10,43 @@ namespace HKW.HKWUtils.Observable;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 可观察命令
|
/// 可观察命令
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {CanExecuteProperty.Value}\\}")]
|
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {IsCanExecute.Value}\\}")]
|
||||||
public class ObservableCommand : ICommand
|
public class ObservableCommand : ObservableClass<ObservableCommand>, ICommand
|
||||||
{
|
{
|
||||||
|
bool _isCanExecute = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 能执行的属性
|
/// 能执行的属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ObservableValue<bool> CanExecuteProperty { get; } = new(true);
|
public bool IsCanExecute
|
||||||
|
{
|
||||||
|
get => _isCanExecute;
|
||||||
|
set => SetProperty(ref _isCanExecute, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _currentCanExecute = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前可执行状态
|
/// 当前可执行状态
|
||||||
|
/// <para>
|
||||||
|
/// 在执行异步事件时会强制为 <see langword="false"/>, 但异步结束后会恢复为 <see cref="IsCanExecute"/> 的值
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ObservableValue<bool> CurrentCanExecute { get; } = new(true);
|
public bool CurrentCanExecute
|
||||||
|
{
|
||||||
|
get => _currentCanExecute;
|
||||||
|
private set => SetProperty(ref _currentCanExecute, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ObservableCommand()
|
public ObservableCommand()
|
||||||
{
|
{
|
||||||
CanExecuteProperty.PropertyChanged += InvokeCanExecuteChanged;
|
PropertyChanged += OnCanExecuteChanged;
|
||||||
CurrentCanExecute.PropertyChanged += InvokeCanExecuteChanged;
|
|
||||||
CurrentCanExecute.ValueChanging += CurrentCanExecute_ValueChanging;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentCanExecute_ValueChanging(
|
private void OnCanExecuteChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
ObservableValue<bool> sender,
|
|
||||||
ValueChangingEventArgs<bool> e
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (e.NewValue is true && CanExecuteProperty.Value is false)
|
CanExecuteChanged?.Invoke(this, new());
|
||||||
e.Cancel = true;
|
|
||||||
else
|
|
||||||
e.Cancel = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InvokeCanExecuteChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
CanExecuteChanged?.Invoke(sender, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ICommand
|
#region ICommand
|
||||||
@ -55,7 +57,7 @@ public class ObservableCommand : ICommand
|
|||||||
/// <returns>能被执行为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
/// <returns>能被执行为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
||||||
public bool CanExecute(object? parameter)
|
public bool CanExecute(object? parameter)
|
||||||
{
|
{
|
||||||
return CurrentCanExecute.Value && CanExecuteProperty.Value;
|
return CurrentCanExecute && IsCanExecute;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -64,71 +66,36 @@ public class ObservableCommand : ICommand
|
|||||||
/// <param name="parameter">参数</param>
|
/// <param name="parameter">参数</param>
|
||||||
public async void Execute(object? parameter)
|
public async void Execute(object? parameter)
|
||||||
{
|
{
|
||||||
|
if (IsCanExecute is not true)
|
||||||
|
return;
|
||||||
ExecuteCommand?.Invoke();
|
ExecuteCommand?.Invoke();
|
||||||
await ExecuteAsync();
|
await ExecuteAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行异步方法, 会在等待中关闭按钮的可执行性, 完成后恢复
|
/// 执行异步方法, 会在等待中修改 <see cref="CurrentCanExecute"/>, 完成后恢复
|
||||||
|
/// <para>
|
||||||
|
/// 若要在执行此方法时触发 <see cref="ExecuteCommand"/> 事件, 请将 <paramref name="runAlone"/> 设置为 <see langword="true"/>
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>等待</returns>
|
/// <param name="runAlone">设置为 <see langword="true"/> 时触发 <see cref="ExecuteCommand"/> 事件</param>
|
||||||
private async Task ExecuteAsync()
|
/// <returns>任务</returns>
|
||||||
|
public async Task ExecuteAsync(bool runAlone = false)
|
||||||
{
|
{
|
||||||
if (AsyncExecuteCommand is null)
|
if (IsCanExecute is not true)
|
||||||
return;
|
return;
|
||||||
CurrentCanExecute.Value = false;
|
if (runAlone)
|
||||||
|
ExecuteCommand?.Invoke();
|
||||||
|
if (ExecuteAsyncCommand is null)
|
||||||
|
return;
|
||||||
|
CurrentCanExecute = false;
|
||||||
foreach (
|
foreach (
|
||||||
var asyncEvent in AsyncExecuteCommand
|
var asyncEvent in ExecuteAsyncCommand
|
||||||
.GetInvocationList()
|
.GetInvocationList()
|
||||||
.Cast<AsyncExecuteEventHandler>()
|
.Cast<ExecuteAsyncEventHandler>()
|
||||||
)
|
)
|
||||||
await asyncEvent.Invoke();
|
await asyncEvent.Invoke();
|
||||||
CurrentCanExecute.Value = true;
|
CurrentCanExecute = true;
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region NotifyReceiver
|
|
||||||
/// <summary>
|
|
||||||
/// 添加通知属性改变后接收器
|
|
||||||
/// <para>
|
|
||||||
/// 添加的接口触发后会执行 <see cref="NotifyCanExecuteReceived"/>
|
|
||||||
/// </para>
|
|
||||||
/// <para>示例:
|
|
||||||
/// <code><![CDATA[
|
|
||||||
/// ObservableValue<string> value = new();
|
|
||||||
/// ObservableCommand command = new();
|
|
||||||
/// command.AddNotifyReceiver(value);
|
|
||||||
/// command.NotifyCanExecuteReceived += (ref bool canExecute) =>
|
|
||||||
/// {
|
|
||||||
/// canExecute = false; // trigger this
|
|
||||||
/// };
|
|
||||||
/// value.EnumValue = "A"; // execute this
|
|
||||||
/// // result: value.EnumValue == "A" , command.CanExecuteProperty == false
|
|
||||||
/// ]]>
|
|
||||||
/// </code></para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="notifies">通知属性改变后接口</param>
|
|
||||||
public void AddNotifyReceiver(params INotifyPropertyChanged[] notifies)
|
|
||||||
{
|
|
||||||
foreach (var notify in notifies)
|
|
||||||
notify.PropertyChanged += Notify_PropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除通知属性改变后接收器
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="notifies">通知属性改变后接口</param>
|
|
||||||
public void RemoveNotifyReceiver(params INotifyPropertyChanged[] notifies)
|
|
||||||
{
|
|
||||||
foreach (var notify in notifies)
|
|
||||||
notify.PropertyChanged -= Notify_PropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Notify_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
var args = new CancelEventArgs();
|
|
||||||
NotifyCanExecuteReceived?.Invoke(this, args);
|
|
||||||
CanExecuteProperty.Value = args.Cancel;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -146,11 +113,6 @@ public class ObservableCommand : ICommand
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步执行事件
|
/// 异步执行事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event AsyncExecuteEventHandler? AsyncExecuteCommand;
|
public event ExecuteAsyncEventHandler? ExecuteAsyncCommand;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 可执行通知接收器事件
|
|
||||||
/// </summary>
|
|
||||||
public event NotifyReceivedEventHandler? NotifyCanExecuteReceived;
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -8,110 +8,112 @@ using System.Windows.Input;
|
|||||||
namespace HKW.HKWUtils.Observable;
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 带参数的可观察命令
|
/// 具有参数的可观察命令
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">参数类型</typeparam>
|
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {IsCanExecute.Value}\\}")]
|
||||||
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {CanExecuteProperty.Value}\\}")]
|
public class ObservableCommand<T> : ObservableClass<ObservableCommand>, ICommand
|
||||||
public class ObservableCommand<T> : ICommand
|
|
||||||
where T : notnull
|
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="ObservableCommand.CanExecuteProperty"/>
|
bool _isCanExecute = true;
|
||||||
public ObservableValue<bool> CanExecuteProperty { get; } = new(true);
|
|
||||||
|
/// <summary>
|
||||||
|
/// 能执行的属性
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCanExecute
|
||||||
|
{
|
||||||
|
get => _isCanExecute;
|
||||||
|
set => SetProperty(ref _isCanExecute, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _currentCanExecute = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前可执行状态
|
/// 当前可执行状态
|
||||||
|
/// <para>
|
||||||
|
/// 在执行异步事件时会强制为 <see langword="false"/>, 但异步结束后会恢复为 <see cref="IsCanExecute"/> 的值
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ObservableValue<bool> CurrentCanExecute { get; } = new(true);
|
public bool CurrentCanExecute
|
||||||
|
{
|
||||||
|
get => _currentCanExecute;
|
||||||
|
private set => SetProperty(ref _currentCanExecute, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ObservableCommand()
|
public ObservableCommand()
|
||||||
{
|
{
|
||||||
CanExecuteProperty.PropertyChanged += InvokeCanExecuteChanged;
|
PropertyChanged += OnCanExecuteChanged;
|
||||||
CurrentCanExecute.PropertyChanged += InvokeCanExecuteChanged;
|
|
||||||
CurrentCanExecute.ValueChanging += CurrentCanExecute_ValueChanging;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentCanExecute_ValueChanging(
|
private void OnCanExecuteChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
ObservableValue<bool> sender,
|
|
||||||
ValueChangingEventArgs<bool> e
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (e.NewValue is true && CanExecuteProperty.Value is false)
|
CanExecuteChanged?.Invoke(this, new());
|
||||||
e.Cancel = true;
|
|
||||||
else
|
|
||||||
e.Cancel = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InvokeCanExecuteChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
CanExecuteChanged?.Invoke(sender, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ICommand
|
#region ICommand
|
||||||
/// <inheritdoc cref="ObservableCommand.CanExecute(object?)"/>
|
/// <summary>
|
||||||
|
/// 能否被执行
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parameter">参数</param>
|
||||||
|
/// <returns>能被执行为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
||||||
public bool CanExecute(object? parameter)
|
public bool CanExecute(object? parameter)
|
||||||
{
|
{
|
||||||
return CurrentCanExecute.Value && CanExecuteProperty.Value;
|
return CurrentCanExecute && IsCanExecute;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ObservableCommand.Execute(object?)"/>
|
/// <summary>
|
||||||
|
/// 执行方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parameter">参数</param>
|
||||||
public async void Execute(object? parameter)
|
public async void Execute(object? parameter)
|
||||||
{
|
{
|
||||||
|
if (IsCanExecute is not true)
|
||||||
|
return;
|
||||||
ExecuteCommand?.Invoke((T)parameter!);
|
ExecuteCommand?.Invoke((T)parameter!);
|
||||||
await ExecuteAsync((T)parameter!);
|
await ExecuteAsync((T)parameter!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ObservableCommand.ExecuteAsync"/>
|
/// <summary>
|
||||||
|
/// 执行异步方法, 会在等待中修改 <see cref="CurrentCanExecute"/>, 完成后恢复
|
||||||
|
/// <para>
|
||||||
|
/// 若要在执行此方法时触发 <see cref="ExecuteCommand"/> 事件, 请将 <paramref name="runAlone"/> 设置为 <see langword="true"/>
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
/// <param name="parameter">参数</param>
|
/// <param name="parameter">参数</param>
|
||||||
private async Task ExecuteAsync(T parameter)
|
/// <param name="runAlone">设置为 <see langword="true"/> 时触发 <see cref="ExecuteCommand"/> 事件</param>
|
||||||
|
/// <returns>任务</returns>
|
||||||
|
public async Task ExecuteAsync(T parameter, bool runAlone = false)
|
||||||
{
|
{
|
||||||
if (AsyncExecuteCommand is null)
|
if (IsCanExecute is not true)
|
||||||
return;
|
return;
|
||||||
CurrentCanExecute.Value = false;
|
if (runAlone)
|
||||||
|
ExecuteCommand?.Invoke(parameter);
|
||||||
|
if (ExecuteAsyncCommand is null)
|
||||||
|
return;
|
||||||
|
CurrentCanExecute = false;
|
||||||
foreach (
|
foreach (
|
||||||
var asyncEvent in AsyncExecuteCommand
|
var asyncEvent in ExecuteAsyncCommand
|
||||||
.GetInvocationList()
|
.GetInvocationList()
|
||||||
.Cast<AsyncExecuteEventHandler<T>>()
|
.Cast<ExecuteAsyncEventHandler<T>>()
|
||||||
)
|
)
|
||||||
await asyncEvent.Invoke(parameter);
|
await asyncEvent.Invoke(parameter);
|
||||||
CurrentCanExecute.Value = true;
|
CurrentCanExecute = true;
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region NotifyReceiver
|
|
||||||
/// <inheritdoc cref="ObservableCommand.AddNotifyReceiver(INotifyPropertyChanged[])"/>
|
|
||||||
public void AddNotifyReceiver(params INotifyPropertyChanged[] notifies)
|
|
||||||
{
|
|
||||||
foreach (var notify in notifies)
|
|
||||||
notify.PropertyChanged += Notify_PropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ObservableCommand.RemoveNotifyReceiver(INotifyPropertyChanged[])"/>
|
|
||||||
public void RemoveNotifyReceiver(params INotifyPropertyChanged[] notifies)
|
|
||||||
{
|
|
||||||
foreach (var notify in notifies)
|
|
||||||
notify.PropertyChanged -= Notify_PropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Notify_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
var args = new CancelEventArgs();
|
|
||||||
NotifyCanExecuteReceived?.Invoke(this, args);
|
|
||||||
CanExecuteProperty.Value = args.Cancel;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
/// <inheritdoc cref="ObservableCommand.CanExecuteChanged"/>
|
/// <summary>
|
||||||
|
/// 能否执行属性改变后事件
|
||||||
|
/// </summary>
|
||||||
public event EventHandler? CanExecuteChanged;
|
public event EventHandler? CanExecuteChanged;
|
||||||
|
|
||||||
/// <inheritdoc cref="ObservableCommand.ExecuteCommand"/>
|
/// <summary>
|
||||||
|
/// 执行事件
|
||||||
|
/// </summary>
|
||||||
public event ExecuteEventHandler<T>? ExecuteCommand;
|
public event ExecuteEventHandler<T>? ExecuteCommand;
|
||||||
|
|
||||||
/// <inheritdoc cref="ObservableCommand.AsyncExecuteCommand"/>
|
/// <summary>
|
||||||
public event AsyncExecuteEventHandler<T>? AsyncExecuteCommand;
|
/// 异步执行事件
|
||||||
|
/// </summary>
|
||||||
/// <inheritdoc cref="ObservableCommand.NotifyCanExecuteReceived"/>
|
public event ExecuteAsyncEventHandler<T>? ExecuteAsyncCommand;
|
||||||
public event NotifyReceivedEventHandler? NotifyCanExecuteReceived;
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace HKW.HKWUtils.Observable;
|
namespace HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
@ -169,55 +170,36 @@ public class ObservableValue<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool Equals(object? obj)
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return Equals(obj as ObservableValue<T>);
|
return Value?.GetHashCode() ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override int GetHashCode()
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
return Guid.GetHashCode();
|
return obj is ObservableValue<T> value
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Value, value.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool Equals(ObservableValue<T>? other)
|
public bool Equals(ObservableValue<T>? other)
|
||||||
{
|
{
|
||||||
return Guid.Equals(other?.Guid) is true;
|
return other is ObservableValue<T> value
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Value, value.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// 值相等
|
public static bool operator ==(ObservableValue<T> a, ObservableValue<T> b)
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">其它可观察值</param>
|
|
||||||
/// <returns>相等为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
|
||||||
public bool ValueEquals(ObservableValue<T> other)
|
|
||||||
{
|
{
|
||||||
return Value?.Equals(other.Value) is true;
|
return EqualityComparer<T>.Default.Equals(a.Value, b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// 判断 <see cref="Value"/> 相等
|
public static bool operator !=(ObservableValue<T> a, ObservableValue<T> b)
|
||||||
/// </summary>
|
|
||||||
/// <param name="value1">左值</param>
|
|
||||||
/// <param name="value2">右值</param>
|
|
||||||
/// <returns>相等为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
|
||||||
public static bool operator ==(ObservableValue<T> value1, ObservableValue<T> value2)
|
|
||||||
{
|
{
|
||||||
return value1.Value?.Equals(value2.Value) is true;
|
return (a == b) is not true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 判断 <see cref="Value"/> 不相等
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value1">左值</param>
|
|
||||||
/// <param name="value2">右值</param>
|
|
||||||
/// <returns>不相等为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
|
||||||
public static bool operator !=(ObservableValue<T> value1, ObservableValue<T> value2)
|
|
||||||
{
|
|
||||||
return value1.Value?.Equals(value2.Value) is not true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
|
9
VPet.ModMaker/Usings.cs
Normal file
9
VPet.ModMaker/Usings.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
global using global::System;
|
||||||
|
global using global::System.Collections.Generic;
|
||||||
|
global using global::System.IO;
|
||||||
|
global using global::System.Linq;
|
||||||
|
global using global::System.Net.Http;
|
||||||
|
global using global::System.Threading;
|
||||||
|
global using global::System.Threading.Tasks;
|
||||||
|
global using global::HKW.HKWUtils;
|
||||||
|
global using global::HKW.HKWUtils.Observable;
|
@ -12,10 +12,9 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using VPet.ModMaker.Models.ModModel;
|
|
||||||
using VPet_Simulator.Core;
|
using VPet_Simulator.Core;
|
||||||
|
|
||||||
namespace HKW.Models;
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 拓展
|
/// 拓展
|
||||||
@ -45,10 +44,9 @@ public static class Extensions
|
|||||||
/// <param name="source">图像资源</param>
|
/// <param name="source">图像资源</param>
|
||||||
public static void CloseStream(this ImageSource source)
|
public static void CloseStream(this ImageSource source)
|
||||||
{
|
{
|
||||||
if (source is BitmapImage image)
|
if (source is not BitmapImage image)
|
||||||
{
|
return;
|
||||||
image.StreamSource?.Close();
|
image.StreamSource?.Close();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -140,16 +138,6 @@ public static class Extensions
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是含有名称的动画
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="graphType"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool IsHasNameAnime(this GraphInfo.GraphType graphType)
|
|
||||||
{
|
|
||||||
return AnimeTypeModel.HasNameAnimes.Contains(graphType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 流内容对比
|
/// 流内容对比
|
||||||
/// </summary>
|
/// </summary>
|
72
VPet.ModMaker/Utils/HashCode.cs
Normal file
72
VPet.ModMaker/Utils/HashCode.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 哈希值
|
||||||
|
/// </summary>
|
||||||
|
public class HashCode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认种子
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultSeed = 114514;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认系数
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultFactor = 1919810;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 组合哈希值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="values">值</param>
|
||||||
|
/// <returns>组合的哈希值</returns>
|
||||||
|
public static int Combine(params object[] values)
|
||||||
|
{
|
||||||
|
return CustomHash(DefaultSeed, DefaultFactor, values.Select(v => v.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 组合哈希值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seed">种子</param>
|
||||||
|
/// <param name="factor">系数</param>
|
||||||
|
/// <param name="values">值</param>
|
||||||
|
/// <returns>组合的哈希值</returns>
|
||||||
|
public static int Combine(int seed, int factor, params object[] values)
|
||||||
|
{
|
||||||
|
return CustomHash(seed, factor, values.Select(v => v.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义组合哈希
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seed">种子</param>
|
||||||
|
/// <param name="factor">系数</param>
|
||||||
|
/// <param name="collection">哈希集合</param>
|
||||||
|
/// <returns>组合的哈希</returns>
|
||||||
|
public static int CustomHash(int seed, int factor, IEnumerable<int> collection)
|
||||||
|
{
|
||||||
|
int hash = seed;
|
||||||
|
foreach (int i in collection)
|
||||||
|
hash = unchecked((hash * factor) + i);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义组合哈希
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seed">种子</param>
|
||||||
|
/// <param name="factor">系数</param>
|
||||||
|
/// <param name="values">哈希集合</param>
|
||||||
|
/// <returns>组合的哈希</returns>
|
||||||
|
public static int CustomHash(int seed, int factor, params int[] values)
|
||||||
|
{
|
||||||
|
return CustomHash(seed, factor, collection: values);
|
||||||
|
}
|
||||||
|
}
|
81
VPet.ModMaker/Utils/ObservableEnumFlags.cs
Normal file
81
VPet.ModMaker/Utils/ObservableEnumFlags.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
using HKW.HKWUtils.Observable;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可观察的枚举标签模型
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">枚举类型</typeparam>
|
||||||
|
public class ObservableEnumFlags<T> : ObservableClass<ObservableEnumFlags<T>>
|
||||||
|
where T : Enum
|
||||||
|
{
|
||||||
|
private T _EnumValue;
|
||||||
|
public T EnumValue
|
||||||
|
{
|
||||||
|
get => _EnumValue;
|
||||||
|
set => SetProperty(ref _EnumValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加枚举命令
|
||||||
|
/// </summary>
|
||||||
|
public ObservableCommand<T> AddCommand { get; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除枚举命令
|
||||||
|
/// </summary>
|
||||||
|
public ObservableCommand<T> RemoveCommand { get; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举类型
|
||||||
|
/// </summary>
|
||||||
|
public Type EnumType = typeof(T);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举基类
|
||||||
|
/// </summary>
|
||||||
|
public Type UnderlyingType { get; } = Enum.GetUnderlyingType(typeof(T));
|
||||||
|
|
||||||
|
public ObservableEnumFlags()
|
||||||
|
{
|
||||||
|
if (Attribute.IsDefined(EnumType, typeof(FlagsAttribute)) is false)
|
||||||
|
throw new Exception($"此枚举类型未使用特性 [{nameof(FlagsAttribute)}]");
|
||||||
|
AddCommand.ExecuteCommand += AddCommand_Execute;
|
||||||
|
RemoveCommand.ExecuteCommand += RemoveCommand_Execute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableEnumFlags(T value)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
EnumValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddCommand_Execute(T v)
|
||||||
|
{
|
||||||
|
if (UnderlyingType == typeof(int))
|
||||||
|
{
|
||||||
|
EnumValue = (T)
|
||||||
|
Enum.Parse(EnumType, (Convert.ToInt32(EnumValue) | Convert.ToInt32(v)).ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new NotImplementedException($"Value type: {UnderlyingType}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveCommand_Execute(T v)
|
||||||
|
{
|
||||||
|
if (UnderlyingType == typeof(int))
|
||||||
|
{
|
||||||
|
EnumValue = (T)
|
||||||
|
Enum.Parse(EnumType, (Convert.ToInt32(EnumValue) & ~Convert.ToInt32(v)).ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new NotImplementedException($"Value type: {UnderlyingType}");
|
||||||
|
}
|
||||||
|
}
|
79
VPet.ModMaker/Utils/ObservablePoint.cs
Normal file
79
VPet.ModMaker/Utils/ObservablePoint.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可观察地点
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">类型</typeparam>
|
||||||
|
public class ObservablePoint<T>
|
||||||
|
: ObservableClass<ObservablePoint<T>>,
|
||||||
|
IEquatable<ObservablePoint<T>>
|
||||||
|
{
|
||||||
|
private T _x;
|
||||||
|
public T X
|
||||||
|
{
|
||||||
|
get => _x;
|
||||||
|
set => SetProperty(ref _x, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T _y;
|
||||||
|
public T Y
|
||||||
|
{
|
||||||
|
get => _y;
|
||||||
|
set => SetProperty(ref _y, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservablePoint() { }
|
||||||
|
|
||||||
|
public ObservablePoint(T x, T y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制一个新的对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>新对象</returns>
|
||||||
|
public ObservablePoint<T> Copy()
|
||||||
|
{
|
||||||
|
return new(X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is ObservablePoint<T> temp
|
||||||
|
&& EqualityComparer<T>.Default.Equals(X, temp.X)
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Y, temp.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Equals(ObservablePoint<T>? other)
|
||||||
|
{
|
||||||
|
return Equals(obj: other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator ==(ObservablePoint<T> a, ObservablePoint<T> b)
|
||||||
|
{
|
||||||
|
return Equals(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator !=(ObservablePoint<T> a, ObservablePoint<T> b)
|
||||||
|
{
|
||||||
|
return Equals(a, b) is not true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
82
VPet.ModMaker/Utils/ObservableRange.cs
Normal file
82
VPet.ModMaker/Utils/ObservableRange.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using HKW.HKWUtils;
|
||||||
|
using HKW.HKWUtils.Observable;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可观察的范围
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">类型</typeparam>
|
||||||
|
public class ObservableRange<T>
|
||||||
|
: ObservableClass<ObservableRange<T>>,
|
||||||
|
IEquatable<ObservableRange<T>>
|
||||||
|
{
|
||||||
|
private T _min;
|
||||||
|
public T Min
|
||||||
|
{
|
||||||
|
get => _min;
|
||||||
|
set => SetProperty(ref _min, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T _max;
|
||||||
|
public T Max
|
||||||
|
{
|
||||||
|
get => _max;
|
||||||
|
set => SetProperty(ref _max, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableRange() { }
|
||||||
|
|
||||||
|
public ObservableRange(T min, T max)
|
||||||
|
{
|
||||||
|
_min = min;
|
||||||
|
_max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制一个新的对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>新对象</returns>
|
||||||
|
public ObservableRange<T> Copy()
|
||||||
|
{
|
||||||
|
return new(Min, Max);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(Min, Max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is ObservableRange<T> temp
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Min, temp.Min)
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Max, temp.Max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Equals(ObservableRange<T>? other)
|
||||||
|
{
|
||||||
|
return Equals(obj: other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator ==(ObservableRange<T> a, ObservableRange<T> b)
|
||||||
|
{
|
||||||
|
return Equals(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator !=(ObservableRange<T> a, ObservableRange<T> b)
|
||||||
|
{
|
||||||
|
return Equals(a, b) is not true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
91
VPet.ModMaker/Utils/ObservableRect.cs
Normal file
91
VPet.ModMaker/Utils/ObservableRect.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using HKW.HKWUtils.Observable;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
|
public class ObservableRect<T> : ObservableClass<ObservableRect<T>>, IEquatable<ObservableRect<T>>
|
||||||
|
{
|
||||||
|
private T _x;
|
||||||
|
public T X
|
||||||
|
{
|
||||||
|
get => _x;
|
||||||
|
set => SetProperty(ref _x, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T _y;
|
||||||
|
public T Y
|
||||||
|
{
|
||||||
|
get => _y;
|
||||||
|
set => SetProperty(ref _y, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T _width;
|
||||||
|
public T Width
|
||||||
|
{
|
||||||
|
get => _width;
|
||||||
|
set => SetProperty(ref _width, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T _heigth;
|
||||||
|
public T Height
|
||||||
|
{
|
||||||
|
get => _heigth;
|
||||||
|
set => SetProperty(ref _heigth, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableRect() { }
|
||||||
|
|
||||||
|
public ObservableRect(T x, T y, T width, T hetght)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Width = width;
|
||||||
|
Height = hetght;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制一个新的对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>新对象</returns>
|
||||||
|
public ObservableRect<T> Copy()
|
||||||
|
{
|
||||||
|
return new(X, Y, Width, Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(X, Y, Width, Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is ObservableRect<T> temp
|
||||||
|
&& EqualityComparer<T>.Default.Equals(X, temp.X)
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Y, temp.Y)
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Width, temp.Width)
|
||||||
|
&& EqualityComparer<T>.Default.Equals(Height, temp.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Equals(ObservableRect<T>? other)
|
||||||
|
{
|
||||||
|
return Equals(obj: other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator ==(ObservableRect<T> a, ObservableRect<T> b)
|
||||||
|
{
|
||||||
|
return Equals(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public static bool operator !=(ObservableRect<T> a, ObservableRect<T> b)
|
||||||
|
{
|
||||||
|
return Equals(a, b) is not true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -5,9 +5,8 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using VPet.ModMaker;
|
|
||||||
|
|
||||||
namespace HKW.Models;
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 工具
|
/// 工具
|
@ -98,6 +98,7 @@
|
|||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Usings.cs" />
|
||||||
<Compile Include="Converters\BrushToMediaColorConverter.cs" />
|
<Compile Include="Converters\BrushToMediaColorConverter.cs" />
|
||||||
<Compile Include="Converters\CalculatorConverter.cs" />
|
<Compile Include="Converters\CalculatorConverter.cs" />
|
||||||
<Compile Include="Converters\EqualsConverter.cs" />
|
<Compile Include="Converters\EqualsConverter.cs" />
|
||||||
@ -110,12 +111,37 @@
|
|||||||
<Compile Include="Converters\RatioMarginConverter.cs" />
|
<Compile Include="Converters\RatioMarginConverter.cs" />
|
||||||
<Compile Include="Converters\MaxConverter.cs" />
|
<Compile Include="Converters\MaxConverter.cs" />
|
||||||
<Compile Include="Converters\MarginConverter.cs" />
|
<Compile Include="Converters\MarginConverter.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\INotifyPropertyChangedX.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\INotifyPropertyChangingX.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\ObservableClass.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\PropertyChangedXEventArgs.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\PropertyChangedXEventHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\PropertyChangingXEventArgs.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableClass\PropertyChangingXEventHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableCommand\ExecuteAsyncEventHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableCommand\ExecuteEventHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableCommand\NotifyReceivedEventHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableCommand\ObservableCommand.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableCommand\ObservableCommandT.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\NotifySenderPropertyChangedHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\ObservableValue.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\ObservableValueGroup.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\ValueChangedEventArgs.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\ValueChangedEventHandler.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\ValueChangingEventArgs.cs" />
|
||||||
|
<Compile Include="SimpleObservable\ObservableValue\ValueChangingEventHandler.cs" />
|
||||||
|
<Compile Include="Utils\ObservableEnumFlags.cs" />
|
||||||
|
<Compile Include="Utils\Expansions.cs" />
|
||||||
|
<Compile Include="Utils\HashCode.cs" />
|
||||||
|
<Compile Include="Utils\ObservableRange.cs" />
|
||||||
|
<Compile Include="Utils\ObservablePoint.cs" />
|
||||||
|
<Compile Include="Utils\ObservableRect.cs" />
|
||||||
|
<Compile Include="Utils\Utils.cs" />
|
||||||
<Compile Include="Models\EnumFlagsVM.cs" />
|
<Compile Include="Models\EnumFlagsVM.cs" />
|
||||||
<Compile Include="Models\I18nData.cs" />
|
<Compile Include="Models\I18nData.cs" />
|
||||||
<Compile Include="Models\ModModel\AnimeModel.cs" />
|
<Compile Include="Models\ModModel\AnimeModel.cs" />
|
||||||
<Compile Include="Models\ModModel\AnimeTypeModel.cs" />
|
<Compile Include="Models\ModModel\AnimeTypeModel.cs" />
|
||||||
<Compile Include="Models\ModModel\ClickTextModel.cs" />
|
<Compile Include="Models\ModModel\ClickTextModel.cs" />
|
||||||
<Compile Include="Models\Expansions.cs" />
|
|
||||||
<Compile Include="Models\ModModel\FoodAnimeModel.cs" />
|
<Compile Include="Models\ModModel\FoodAnimeModel.cs" />
|
||||||
<Compile Include="Models\ModModel\FoodAnimeTypeModel.cs" />
|
<Compile Include="Models\ModModel\FoodAnimeTypeModel.cs" />
|
||||||
<Compile Include="Models\ModModel\FoodLocationModel.cs" />
|
<Compile Include="Models\ModModel\FoodLocationModel.cs" />
|
||||||
@ -136,18 +162,6 @@
|
|||||||
<Compile Include="Models\ModModel\WorkModel.cs" />
|
<Compile Include="Models\ModModel\WorkModel.cs" />
|
||||||
<Compile Include="Resources\NativeResources.cs" />
|
<Compile Include="Resources\NativeResources.cs" />
|
||||||
<Compile Include="NativeStyles.cs" />
|
<Compile Include="NativeStyles.cs" />
|
||||||
<Compile Include="SimpleObservable\ObservableCommand\AsyncExecuteEventHandler.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableCommand\ExecuteEventHandler.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableCommand\NotifyReceivedEventHandler.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableCommand\ObservableCommand.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableCommand\ObservableCommandT.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\NotifySenderPropertyChangedHandler.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\ObservableValue.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\ObservableValueGroup.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\ValueChangedEventArgs.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\ValueChangedEventHandler.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\ValueChangingEventArgs.cs" />
|
|
||||||
<Compile Include="SimpleObservable\ObservableValue\ValueChangingEventHandler.cs" />
|
|
||||||
<Compile Include="ViewModels\ModEdit\AddCultureWindowVM.cs" />
|
<Compile Include="ViewModels\ModEdit\AddCultureWindowVM.cs" />
|
||||||
<Compile Include="ViewModels\ModEdit\AnimeEdit\FoodAnimeEditWindowVM.cs" />
|
<Compile Include="ViewModels\ModEdit\AnimeEdit\FoodAnimeEditWindowVM.cs" />
|
||||||
<Compile Include="ViewModels\ModEdit\AnimeEdit\AnimeEditWindowVM.cs" />
|
<Compile Include="ViewModels\ModEdit\AnimeEdit\AnimeEditWindowVM.cs" />
|
||||||
@ -217,7 +231,6 @@
|
|||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Models\Utils.cs" />
|
|
||||||
<Compile Include="Views\ModEdit\FoodEdit\FoodEditWindow.xaml.cs">
|
<Compile Include="Views\ModEdit\FoodEdit\FoodEditWindow.xaml.cs">
|
||||||
<DependentUpon>FoodEditWindow.xaml</DependentUpon>
|
<DependentUpon>FoodEditWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
@ -123,7 +123,7 @@ public class AnimeEditWindowVM
|
|||||||
|
|
||||||
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||||
|
|
||||||
PlayCommand.AsyncExecuteCommand += PlayCommand_AsyncExecuteEvent;
|
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||||
AddAnimeCommand.ExecuteCommand += AddAnimeCommand_ExecuteEvent;
|
AddAnimeCommand.ExecuteCommand += AddAnimeCommand_ExecuteEvent;
|
||||||
RemoveAnimeCommand.ExecuteCommand += RemoveAnimeCommand_ExecuteEvent;
|
RemoveAnimeCommand.ExecuteCommand += RemoveAnimeCommand_ExecuteEvent;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Panuon.WPF.UI;
|
using Panuon.WPF.UI;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
@ -24,7 +24,6 @@ public class FoodAnimeEditWindowVM
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PetModel CurrentPet { get; set; }
|
public PetModel CurrentPet { get; set; }
|
||||||
|
|
||||||
// TODO: 使用内部资源
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认食物图片
|
/// 默认食物图片
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -211,7 +210,7 @@ public class FoodAnimeEditWindowVM
|
|||||||
|
|
||||||
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||||
|
|
||||||
PlayCommand.AsyncExecuteCommand += PlayCommand_AsyncExecuteEvent;
|
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||||
ReplaceFoodImageCommand.ExecuteCommand += ChangeFoodImageCommand_ExecuteEvent;
|
ReplaceFoodImageCommand.ExecuteCommand += ChangeFoodImageCommand_ExecuteEvent;
|
||||||
ResetFoodImageCommand.ExecuteCommand += ResetFoodImageCommand_ExecuteEvent;
|
ResetFoodImageCommand.ExecuteCommand += ResetFoodImageCommand_ExecuteEvent;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -296,7 +296,7 @@ public class I18nEditWindowVM
|
|||||||
{
|
{
|
||||||
foreach (var pet in model.Pets)
|
foreach (var pet in model.Pets)
|
||||||
{
|
{
|
||||||
if (pet.IsSimplePetModel)
|
if (pet.FromMain.Value)
|
||||||
continue;
|
continue;
|
||||||
AddData(pet.Id, pet, (m) => m.Name);
|
AddData(pet.Id, pet, (m) => m.Name);
|
||||||
AddData(pet.PetNameId, pet, (m) => m.PetName);
|
AddData(pet.PetNameId, pet, (m) => m.PetName);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -18,7 +18,6 @@ using Panuon.WPF.UI;
|
|||||||
using VPet.ModMaker.Views.ModEdit.I18nEdit;
|
using VPet.ModMaker.Views.ModEdit.I18nEdit;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Ookii.Dialogs.Wpf;
|
using Ookii.Dialogs.Wpf;
|
||||||
using HKW.Models;
|
|
||||||
|
|
||||||
namespace VPet.ModMaker.ViewModels.ModEdit;
|
namespace VPet.ModMaker.ViewModels.ModEdit;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -66,11 +66,12 @@ public class PetPageVM
|
|||||||
|
|
||||||
public void Edit(PetModel model)
|
public void Edit(PetModel model)
|
||||||
{
|
{
|
||||||
if (model.IsSimplePetModel)
|
if (
|
||||||
{
|
model.FromMain.Value
|
||||||
MessageBox.Show("这是本体自带的宠物, 无法编辑".Translate());
|
&& MessageBox.Show("这是本体自带的宠物, 确定要编辑吗".Translate(), "", MessageBoxButton.YesNo)
|
||||||
|
is not MessageBoxResult.Yes
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
var window = new PetEditWindow();
|
var window = new PetEditWindow();
|
||||||
var vm = window.ViewModel;
|
var vm = window.ViewModel;
|
||||||
vm.OldPet = model;
|
vm.OldPet = model;
|
||||||
@ -86,7 +87,7 @@ public class PetPageVM
|
|||||||
|
|
||||||
private void Remove(PetModel model)
|
private void Remove(PetModel model)
|
||||||
{
|
{
|
||||||
if (model.IsSimplePetModel)
|
if (model.FromMain.Value)
|
||||||
{
|
{
|
||||||
MessageBox.Show("这是本体自带的宠物, 无法删除".Translate());
|
MessageBox.Show("这是本体自带的宠物, 无法删除".Translate());
|
||||||
return;
|
return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using HKW.Models;
|
using LinePutScript.Localization.WPF;
|
||||||
using LinePutScript.Localization.WPF;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
x:Name="ComboBox_Pet"
|
x:Name="ComboBox_Pet"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
||||||
DisplayMemberPath="Id.Value"
|
|
||||||
ItemsSource="{Binding Pets}"
|
ItemsSource="{Binding Pets}"
|
||||||
SelectedItem="{Binding CurrentPet.Value}"
|
SelectedItem="{Binding CurrentPet.Value}"
|
||||||
Style="{DynamicResource StandardComboBoxStyle}">
|
Style="{DynamicResource StandardComboBoxStyle}">
|
||||||
@ -48,6 +47,14 @@
|
|||||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
||||||
</Style>
|
</Style>
|
||||||
</ComboBox.ItemContainerStyle>
|
</ComboBox.ItemContainerStyle>
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding Id.Value}" />
|
||||||
|
<TextBlock IsEnabled="{Binding FromMain, Converter={StaticResource FalseToCollapsedConverter}}" Text="{ll:Str {} (来自本体)}" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
|
@ -348,7 +348,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Rect.Width.Value}" />
|
Value="{Binding Rect.Width}" />
|
||||||
<Grid Grid.Row="4" Grid.ColumnSpan="2">
|
<Grid Grid.Row="4" Grid.ColumnSpan="2">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
@ -360,7 +360,7 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Content="X:" />
|
<Label Content="X:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Rect.X.Value}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Rect.X}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Column="1">
|
<Grid Grid.Column="1">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@ -368,7 +368,7 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Content="Y:" />
|
<Label Content="Y:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Rect.Y.Value}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Rect.Y}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -380,7 +380,6 @@
|
|||||||
</Expander>
|
</Expander>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@ -433,7 +432,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Width.Value" />
|
<Binding Path="CurrentFoodLocationModel.Value.Rect.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -442,8 +441,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.X.Value" />
|
<Binding Path="CurrentFoodLocationModel.Value.Rect.X" />
|
||||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Y.Value" />
|
<Binding Path="CurrentFoodLocationModel.Value.Rect.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -481,7 +480,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Width.Value" />
|
<Binding Path="CurrentFoodLocationModel.Value.Rect.Width" />
|
||||||
<Binding Source="1" />
|
<Binding Source="1" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -490,8 +489,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Source="1" />
|
<Binding Source="1" />
|
||||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.X.Value" />
|
<Binding Path="CurrentFoodLocationModel.Value.Rect.X" />
|
||||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Y.Value" />
|
<Binding Path="CurrentFoodLocationModel.Value.Rect.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using HKW.Models;
|
using LinePutScript.Localization.WPF;
|
||||||
using LinePutScript.Localization.WPF;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using HKW.Models;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
x:Name="ComboBox_Pet"
|
x:Name="ComboBox_Pet"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
||||||
DisplayMemberPath="Id.Value"
|
|
||||||
ItemsSource="{Binding Pets}"
|
ItemsSource="{Binding Pets}"
|
||||||
SelectedItem="{Binding CurrentPet.Value}"
|
SelectedItem="{Binding CurrentPet.Value}"
|
||||||
Style="{DynamicResource StandardComboBoxStyle}">
|
Style="{DynamicResource StandardComboBoxStyle}">
|
||||||
@ -48,6 +47,14 @@
|
|||||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
||||||
</Style>
|
</Style>
|
||||||
</ComboBox.ItemContainerStyle>
|
</ComboBox.ItemContainerStyle>
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding Id.Value}" />
|
||||||
|
<TextBlock IsEnabled="{Binding FromMain.Value, Converter={StaticResource FalseToCollapsedConverter}}" Text="{ll:Str {} (来自本体)}" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchHeadRect.Value.Width.Value" />
|
<Binding Path="Pet.Value.TouchHeadRect.Value.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
<Setter Property="Height">
|
<Setter Property="Height">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchHeadRect.Value.Height.Value" />
|
<Binding Path="Pet.Value.TouchHeadRect.Value.Height" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -89,8 +89,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.TouchHeadRect.Value.X.Value" />
|
<Binding Path="Pet.Value.TouchHeadRect.Value.X" />
|
||||||
<Binding Path="Pet.Value.TouchHeadRect.Value.Y.Value" />
|
<Binding Path="Pet.Value.TouchHeadRect.Value.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -103,7 +103,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchBodyRect.Value.Width.Value" />
|
<Binding Path="Pet.Value.TouchBodyRect.Value.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -111,7 +111,7 @@
|
|||||||
<Setter Property="Height">
|
<Setter Property="Height">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchBodyRect.Value.Height.Value" />
|
<Binding Path="Pet.Value.TouchBodyRect.Value.Height" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -120,8 +120,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.TouchBodyRect.Value.X.Value" />
|
<Binding Path="Pet.Value.TouchBodyRect.Value.X" />
|
||||||
<Binding Path="Pet.Value.TouchBodyRect.Value.Y.Value" />
|
<Binding Path="Pet.Value.TouchBodyRect.Value.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -134,7 +134,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Value.Width.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -142,7 +142,7 @@
|
|||||||
<Setter Property="Height">
|
<Setter Property="Height">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Value.Height.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Height" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -151,8 +151,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Value.X.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.X" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Value.Y.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Happy.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -165,7 +165,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Value.Width.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -173,7 +173,7 @@
|
|||||||
<Setter Property="Height">
|
<Setter Property="Height">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Value.Height.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Height" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -182,8 +182,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Value.X.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.X" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Value.Y.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Nomal.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -196,7 +196,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.Width.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -204,7 +204,7 @@
|
|||||||
<Setter Property="Height">
|
<Setter Property="Height">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.Height.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Height" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -213,8 +213,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.X.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.X" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.Y.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.PoorCondition.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -227,7 +227,7 @@
|
|||||||
<Setter Property="Width">
|
<Setter Property="Width">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Value.Width.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Width" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -235,7 +235,7 @@
|
|||||||
<Setter Property="Height">
|
<Setter Property="Height">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Value.Height.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Height" />
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@ -244,8 +244,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Value.X.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.X" />
|
||||||
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Value.Y.Value" />
|
<Binding Path="Pet.Value.TouchRaisedRect.Value.Ill.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -264,8 +264,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.Happy.Value.X.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.Happy.X" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.Happy.Value.Y.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.Happy.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -284,8 +284,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.Nomal.Value.X.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.Nomal.X" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.Nomal.Value.Y.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.Nomal.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -304,8 +304,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.PoorCondition.Value.X.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.PoorCondition.X" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.PoorCondition.Value.Y.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.PoorCondition.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -324,8 +324,8 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||||
<Binding Path="LengthRatio.Value" />
|
<Binding Path="LengthRatio.Value" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.Ill.Value.X.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.Ill.X" />
|
||||||
<Binding Path="Pet.Value.RaisePoint.Value.Ill.Value.Y.Value" />
|
<Binding Path="Pet.Value.RaisePoint.Value.Ill.Y" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
@ -414,12 +414,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchHeadRect.Value.X.Value}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchHeadRect.Value.X}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchHeadRect.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchHeadRect.Value.Y, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
@ -427,7 +427,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Pet.Value.TouchHeadRect.Value.Width.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchHeadRect.Value.Width, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -436,7 +436,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Value="{Binding Pet.Value.TouchHeadRect.Value.Height.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchHeadRect.Value.Height, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid>
|
<Grid>
|
||||||
@ -461,12 +461,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchBodyRect.Value.X.Value}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchBodyRect.Value.X}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchBodyRect.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchBodyRect.Value.Y, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
@ -474,7 +474,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Pet.Value.TouchBodyRect.Value.Width.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchBodyRect.Value.Width, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -483,7 +483,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Value="{Binding Pet.Value.TouchBodyRect.Value.Height.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchBodyRect.Value.Height, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Expander Header="{ll:Str 提起范围}">
|
<Expander Header="{ll:Str 提起范围}">
|
||||||
@ -516,12 +516,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Y, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
@ -529,7 +529,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Value.Width.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Width, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -538,7 +538,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Value.Height.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.Happy.Height, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="ToggleButton_TouchRaisedRect_NomalState"
|
x:Name="ToggleButton_TouchRaisedRect_NomalState"
|
||||||
@ -562,12 +562,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Y, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
@ -575,7 +575,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Value.Width.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Width, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -584,7 +584,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Value.Height.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.Nomal.Height, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="ToggleButton_TouchRaisedRect_PoorConditionState"
|
x:Name="ToggleButton_TouchRaisedRect_PoorConditionState"
|
||||||
@ -608,12 +608,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Y, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
@ -621,7 +621,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.Width.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Width, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -630,7 +630,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Value.Height.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.PoorCondition.Height, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="ToggleButton_TouchRaisedRect_IllState"
|
x:Name="ToggleButton_TouchRaisedRect_IllState"
|
||||||
@ -654,12 +654,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Y, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
@ -667,7 +667,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Value.Width.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Width, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -676,7 +676,7 @@
|
|||||||
<pu:NumberInput
|
<pu:NumberInput
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Value.Height.Value, Mode=TwoWay}" />
|
Value="{Binding Pet.Value.TouchRaisedRect.Value.Ill.Height, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Expander>
|
</Expander>
|
||||||
@ -709,12 +709,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.Happy.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.Happy.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.Happy.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.Happy.Y, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="ToggleButton_RaisePoint_Nomal"
|
x:Name="ToggleButton_RaisePoint_Nomal"
|
||||||
@ -737,12 +737,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.Nomal.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.Nomal.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.Nomal.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.Nomal.Y, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="ToggleButton_RaisePoint_PoorCondition"
|
x:Name="ToggleButton_RaisePoint_PoorCondition"
|
||||||
@ -765,12 +765,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.PoorCondition.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.PoorCondition.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.PoorCondition.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.PoorCondition.Y, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="ToggleButton_RaisePoint_Ill"
|
x:Name="ToggleButton_RaisePoint_Ill"
|
||||||
@ -793,12 +793,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Background="{x:Null}" Content="x:" />
|
<Label Background="{x:Null}" Content="x:" />
|
||||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.Ill.Value.X.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.Value.RaisePoint.Value.Ill.X, Mode=TwoWay}" />
|
||||||
<Label
|
<Label
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Background="{x:Null}"
|
Background="{x:Null}"
|
||||||
Content="y:" />
|
Content="y:" />
|
||||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.Ill.Value.Y.Value, Mode=TwoWay}" />
|
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.Value.RaisePoint.Value.Ill.Y, Mode=TwoWay}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Expander>
|
</Expander>
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
MinWidth="150"
|
MinWidth="150"
|
||||||
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
||||||
DisplayMemberPath="Id.Value"
|
|
||||||
ItemsSource="{Binding Pets}"
|
ItemsSource="{Binding Pets}"
|
||||||
SelectedItem="{Binding CurrentPet.Value}"
|
SelectedItem="{Binding CurrentPet.Value}"
|
||||||
Style="{DynamicResource StandardComboBoxStyle}">
|
Style="{DynamicResource StandardComboBoxStyle}">
|
||||||
@ -52,6 +51,14 @@
|
|||||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
||||||
</Style>
|
</Style>
|
||||||
</ComboBox.ItemContainerStyle>
|
</ComboBox.ItemContainerStyle>
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding Id.Value}" />
|
||||||
|
<TextBlock IsEnabled="{Binding FromMain.Value, Converter={StaticResource FalseToCollapsedConverter}}" Text="{ll:Str {} (来自本体)}" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
|
Loading…
Reference in New Issue
Block a user