mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
修复 多语言编辑器Id重复问题
This commit is contained in:
parent
b163719b69
commit
bdb47b0124
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
@ -202,4 +203,62 @@ public static class Extensions
|
||||
{
|
||||
return $"{cultureInfo.DisplayName} [{cultureInfo.Name}]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取目标
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <param name="weakReference">弱引用</param>
|
||||
/// <returns>获取成功返回目标值, 获取失败则返回 <see langword="null"/></returns>
|
||||
public static T? GetTarget<T>(this WeakReference<T> weakReference)
|
||||
where T : class
|
||||
{
|
||||
return weakReference.TryGetTarget(out var t) ? t : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 枚举出带有索引值的枚举值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
/// <param name="collection">集合</param>
|
||||
/// <returns>带有索引的枚举值</returns>
|
||||
public static IEnumerable<ItemInfo<T>> Enumerate<T>(this IEnumerable<T> collection)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var item in collection)
|
||||
yield return new(index++, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 项信息
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("[{Index}, {Value}]")]
|
||||
public readonly struct ItemInfo<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 索引值
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public T Value { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="index">索引值</param>
|
||||
public ItemInfo(int index, T value)
|
||||
{
|
||||
Index = index;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Index}, {Value}]";
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
[DebuggerDisplay("{Id}, Count = {Datas.Count}")]
|
||||
public class I18nData
|
||||
{
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public ObservableCollection<string> Cultures { get; } = new();
|
||||
public ObservableCollection<ObservableValue<string>> Datas { get; } = new();
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
{
|
||||
DescriptionId.Value = $"{n}_{nameof(DescriptionId)}";
|
||||
};
|
||||
ReferencePrice.AddNotifyReceiver(
|
||||
ReferencePrice.AddNotifySender(
|
||||
Strength,
|
||||
StrengthFood,
|
||||
StrengthDrink,
|
||||
@ -109,9 +109,9 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
Likability,
|
||||
Exp
|
||||
);
|
||||
ReferencePrice.NotifyReceived += (ref double v) =>
|
||||
ReferencePrice.SenderPropertyChanged += (s, _) =>
|
||||
{
|
||||
v = Math.Floor(SetValueToFood(_food).RealPrice);
|
||||
s.Value = Math.Floor(SetValueToFood(_food).RealPrice);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -105,11 +105,11 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
PetNameId.Value = $"{n}_{nameof(PetNameId)}";
|
||||
DescriptionId.Value = $"{n}_{nameof(DescriptionId)}";
|
||||
};
|
||||
AnimeCount.AddNotifyReceiver(Animes);
|
||||
AnimeCount.AddNotifyReceiver(FoodAnimes);
|
||||
AnimeCount.NotifyReceived += (ref int v) =>
|
||||
AnimeCount.AddNotifySender(Animes);
|
||||
AnimeCount.AddNotifySender(FoodAnimes);
|
||||
AnimeCount.SenderPropertyChanged += (s, _) =>
|
||||
{
|
||||
v = Animes.Count + FoodAnimes.Count;
|
||||
s.Value = Animes.Count + FoodAnimes.Count;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
|
||||
public WorkModel()
|
||||
{
|
||||
IsOverLoad.AddNotifyReceiver(
|
||||
IsOverLoad.AddNotifySender(
|
||||
WorkType,
|
||||
MoneyBase,
|
||||
MoneyLevel,
|
||||
@ -141,9 +141,9 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
LevelLimit,
|
||||
FinishBonus
|
||||
);
|
||||
IsOverLoad.NotifyReceived += (ref bool v) =>
|
||||
IsOverLoad.SenderPropertyChanged += (s, _) =>
|
||||
{
|
||||
v = VPet_Simulator.Windows.Interface.ExtensionFunction.IsOverLoad(ToWork());
|
||||
s.Value = VPet_Simulator.Windows.Interface.ExtensionFunction.IsOverLoad(ToWork());
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -65,50 +65,4 @@ public static class Utils
|
||||
}
|
||||
return bitmapImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 枚举出带有索引值的枚举值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
/// <param name="collection">集合</param>
|
||||
/// <returns>带有索引的枚举值</returns>
|
||||
public static IEnumerable<ItemInfo<T>> Enumerate<T>(this IEnumerable<T> collection)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var item in collection)
|
||||
yield return new(index++, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 项信息
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("[{Index}, {Value}]")]
|
||||
public readonly struct ItemInfo<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 索引值
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public T Value { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="index">索引值</param>
|
||||
public ItemInfo(int index, T value)
|
||||
{
|
||||
Index = index;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Index}, {Value}]";
|
||||
}
|
||||
}
|
||||
|
@ -2,55 +2,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HKW.HKWViewModels.SimpleObservable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("{Value}")]
|
||||
public class ObservableValue<T>
|
||||
[DebuggerDisplay("\\{ObservableValue, Value = {Value}\\}")]
|
||||
public class ObservableValue
|
||||
: INotifyPropertyChanging,
|
||||
INotifyPropertyChanged,
|
||||
IEquatable<ObservableValue<T>>
|
||||
IEquatable<ObservableValue>
|
||||
{
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private T _value = default!;
|
||||
private object _value = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 当前值
|
||||
/// </summary>
|
||||
public T Value
|
||||
public object Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
if (_value?.Equals(value) is true)
|
||||
return;
|
||||
NotifyPropertyChanging();
|
||||
var oldValue = _value;
|
||||
if (NotifyPropertyChanging(oldValue, value))
|
||||
return;
|
||||
_value = value;
|
||||
NotifyPropertyChanged(oldValue, value);
|
||||
NotifyPropertyChanged(oldValue!, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 含有值
|
||||
/// 包含值
|
||||
/// </summary>
|
||||
public bool HasValue => Value != null;
|
||||
|
||||
/// <summary>
|
||||
/// 唯一标识符
|
||||
/// </summary>
|
||||
public Guid Guid { get; } = Guid.NewGuid();
|
||||
|
||||
#region Ctor
|
||||
/// <inheritdoc/>
|
||||
public ObservableValue() { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="value">初始值</param>
|
||||
public ObservableValue(T value)
|
||||
public ObservableValue(object value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
@ -60,16 +60,10 @@ public class ObservableValue<T>
|
||||
/// <summary>
|
||||
/// 通知属性改变前
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <returns>取消改变</returns>
|
||||
private bool NotifyPropertyChanging(T oldValue, T newValue)
|
||||
protected void NotifyPropertyChanging()
|
||||
{
|
||||
PropertyChanging?.Invoke(this, new(nameof(Value)));
|
||||
var cancel = false;
|
||||
// 若全部事件取消改变 则取消改变
|
||||
ValueChanging?.Invoke(oldValue, newValue, ref cancel);
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -77,60 +71,121 @@ public class ObservableValue<T>
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
private void NotifyPropertyChanged(T oldValue, T newValue)
|
||||
protected void NotifyPropertyChanged(object oldValue, object newValue)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new(nameof(Value)));
|
||||
ValueChanged?.Invoke(oldValue, newValue);
|
||||
if (oldValue is null || newValue is null)
|
||||
PropertyChanged?.Invoke(this, new(nameof(HasValue)));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NotifyReceiver
|
||||
#region NotifySender
|
||||
/// <summary>
|
||||
/// 添加通知属性改变后接收器
|
||||
/// 通知发送者
|
||||
/// </summary>
|
||||
public ICollection<ObservableValue> NotifySenders => _notifySenders.Values;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private readonly Dictionary<Guid, ObservableValue> _notifySenders = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加通知发送者
|
||||
/// <para>
|
||||
/// 添加的接口触发后会执行 <see cref="NotifyReceived"/>
|
||||
/// 添加的发送者改变后会执行 <see cref="SenderPropertyChanged"/>
|
||||
/// </para>
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// ObservableValue<string> value1 = new();
|
||||
/// ObservableValue<string> value2 = new();
|
||||
/// value2.AddNotifyReceiver(value1);
|
||||
/// value2.NotifyReceived += (ref string v) =>
|
||||
/// value2.AddNotifySender(value1);
|
||||
/// value2.NotifyReceived += (source, sender) =>
|
||||
/// {
|
||||
/// v = "B"; // trigger this
|
||||
/// source.Value = sender.Value;
|
||||
/// };
|
||||
/// value1.Value = "A"; // execute this
|
||||
/// // result: value1.Value == "A" , value2.Value == "B"
|
||||
/// value1.Value = "A";
|
||||
/// // value1.Value == "A", value2.Value == "A"
|
||||
/// ]]>
|
||||
/// </code></para>
|
||||
/// </summary>
|
||||
/// <param name="notifies">通知属性改变后接口</param>
|
||||
public void AddNotifyReceiver(params INotifyPropertyChanged[] notifies)
|
||||
/// <param name="items">发送者</param>
|
||||
public void AddNotifySender(params ObservableValue[] items)
|
||||
{
|
||||
foreach (var notify in notifies)
|
||||
notify.PropertyChanged += Notify_PropertyChanged;
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.PropertyChanged += Notify_SenderPropertyChanged;
|
||||
_notifySenders.Add(item.Guid, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除通知属性改变后接收器
|
||||
/// 添加通知发送者
|
||||
/// <para>
|
||||
/// 注: 此方法添加的发送者不会被记录到 <see cref="NotifySenders"/> 中
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="notifies">通知属性改变后接口</param>
|
||||
public void RemoveNotifyReceiver(params INotifyPropertyChanged[] notifies)
|
||||
/// <param name="notices">发送者</param>
|
||||
public void AddNotifySender(params INotifyPropertyChanged[] notices)
|
||||
{
|
||||
foreach (var notify in notifies)
|
||||
notify.PropertyChanged -= Notify_PropertyChanged;
|
||||
foreach (var item in notices)
|
||||
{
|
||||
item.PropertyChanged += Notify_SenderPropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void Notify_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
/// <summary>
|
||||
/// 删除通知发送者
|
||||
/// </summary>
|
||||
/// <param name="items">发送者</param>
|
||||
public void RemoveNotifySender(params ObservableValue[] items)
|
||||
{
|
||||
var temp = Value;
|
||||
NotifyReceived?.Invoke(ref temp);
|
||||
Value = temp;
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.PropertyChanged -= Notify_SenderPropertyChanged;
|
||||
_notifySenders.Remove(item.Guid);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除通知发送者
|
||||
/// <para>
|
||||
/// 注: 此方法删除的发送者不会从 <see cref="NotifySenders"/> 中删除
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="notices">发送者</param>
|
||||
public void RemoveNotifySender(params INotifyPropertyChanged[] notices)
|
||||
{
|
||||
foreach (var item in notices)
|
||||
{
|
||||
item.PropertyChanged -= Notify_SenderPropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空通知发送者
|
||||
/// </summary>
|
||||
public void ClearNotifySender()
|
||||
{
|
||||
foreach (var sender in _notifySenders.Values)
|
||||
sender.PropertyChanged -= Notify_SenderPropertyChanged;
|
||||
_notifySenders.Clear();
|
||||
}
|
||||
|
||||
private void Notify_SenderPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
NotifySenderPropertyChanged(this, sender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知接收事件
|
||||
/// </summary>
|
||||
/// <param name="source">源</param>
|
||||
/// <param name="sender">发送者</param>
|
||||
protected void NotifySenderPropertyChanged(ObservableValue source, object? sender)
|
||||
{
|
||||
SenderPropertyChanged?.Invoke(source, sender);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Other
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
@ -141,7 +196,7 @@ public class ObservableValue<T>
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return Equals(obj as ObservableValue<T>);
|
||||
return Equals(obj as ObservableValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@ -151,9 +206,9 @@ public class ObservableValue<T>
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableValue<T>? other)
|
||||
public bool Equals(ObservableValue? other)
|
||||
{
|
||||
return Value?.Equals(other) is true;
|
||||
return Guid.Equals(other?.Guid) is true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -162,7 +217,7 @@ public class ObservableValue<T>
|
||||
/// <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)
|
||||
public static bool operator ==(ObservableValue value1, ObservableValue value2)
|
||||
{
|
||||
return value1.Value?.Equals(value2.Value) is true;
|
||||
}
|
||||
@ -173,7 +228,7 @@ public class ObservableValue<T>
|
||||
/// <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)
|
||||
public static bool operator !=(ObservableValue value1, ObservableValue value2)
|
||||
{
|
||||
return value1.Value?.Equals(value2.Value) is not true;
|
||||
}
|
||||
@ -192,41 +247,17 @@ public class ObservableValue<T>
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变前事件
|
||||
/// 通知接收事件
|
||||
/// </summary>
|
||||
public event ValueChangingEventHandler? ValueChanging;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件
|
||||
/// </summary>
|
||||
public event ValueChangedEventHandler? ValueChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 通知接收器事件
|
||||
/// </summary>
|
||||
public event NotifyReceivedHandler? NotifyReceived;
|
||||
public event NotifySenderPropertyChangedHandler? SenderPropertyChanged;
|
||||
#endregion
|
||||
|
||||
#region Delegate
|
||||
/// <summary>
|
||||
/// 值改变事件
|
||||
/// 通知发送者属性改变接收器
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <param name="cancel">取消</param>
|
||||
public delegate void ValueChangingEventHandler(T oldValue, T newValue, ref bool cancel);
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public delegate void ValueChangedEventHandler(T oldValue, T newValue);
|
||||
|
||||
/// <summary>
|
||||
/// 通知接收器
|
||||
/// </summary>
|
||||
/// <param name="value">引用值</param>
|
||||
public delegate void NotifyReceivedHandler(ref T value);
|
||||
/// <param name="source">源</param>
|
||||
/// <param name="sender">发送者</param>
|
||||
public delegate void NotifySenderPropertyChangedHandler(ObservableValue source, object? sender);
|
||||
#endregion
|
||||
}
|
||||
|
149
VPet.ModMaker/SimpleObservable/ObservableValueGroup.cs
Normal file
149
VPet.ModMaker/SimpleObservable/ObservableValueGroup.cs
Normal file
@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HKW.HKWViewModels.SimpleObservable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察值组合
|
||||
/// <para>示例:<code><![CDATA[
|
||||
/// var value1 = new ObservableValue<string>();
|
||||
/// var value2 = new ObservableValue<string>();
|
||||
/// var group = new ObservableValueGroup<string>() { value1, value2 };
|
||||
/// value1.Value = "A";
|
||||
/// // value1 == "A", value2 == "A"
|
||||
/// group.Remove(value1);
|
||||
/// value1.Value = "C";
|
||||
/// // value1 == "C", value2 == "A"]]></code></para>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
[DebuggerDisplay("\\{ObservableValueGroup, Count = {Count}\\}")]
|
||||
public class ObservableValueGroup<T> : IEnumerable<ObservableValue<T>?>
|
||||
{
|
||||
/// <summary>
|
||||
/// 数量
|
||||
/// </summary>
|
||||
public int Count => _bindingValues.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 在添加的时候改变值 (如果分组中存在值)
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool ChangeOnAdd { get; set; } = false;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private readonly Dictionary<Guid, WeakReference<ObservableValue<T>>> _bindingValues = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加项
|
||||
/// </summary>
|
||||
/// <param name="items">项</param>
|
||||
public void Add(params ObservableValue<T>[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
AddX(item);
|
||||
}
|
||||
|
||||
private void AddX(ObservableValue<T> item)
|
||||
{
|
||||
if (item.Group is not null)
|
||||
throw new ArgumentException("item.Group must be null", nameof(item));
|
||||
_bindingValues.Add(item.Guid, new(item));
|
||||
item.ValueChanged -= Item_ValueChanged;
|
||||
if (ChangeOnAdd)
|
||||
{
|
||||
foreach (var bindingValue in _bindingValues)
|
||||
{
|
||||
if (bindingValue.Value.TryGetTarget(out var target))
|
||||
{
|
||||
item.Value = target.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
item.ValueChanged += Item_ValueChanged;
|
||||
item.Group = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除项
|
||||
/// </summary>
|
||||
/// <param name="items">项</param>
|
||||
public void Remove(params ObservableValue<T>[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
RemoveX(item);
|
||||
}
|
||||
|
||||
private void RemoveX(ObservableValue<T> item)
|
||||
{
|
||||
var result = _bindingValues.Remove(item.Guid);
|
||||
if (result)
|
||||
{
|
||||
item.ValueChanged -= Item_ValueChanged;
|
||||
item.Group = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空分组
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var bindingValue in _bindingValues)
|
||||
{
|
||||
if (bindingValue.Value.TryGetTarget(out var target))
|
||||
{
|
||||
target.ValueChanged -= Item_ValueChanged;
|
||||
target.Group = null;
|
||||
}
|
||||
}
|
||||
_bindingValues.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找项
|
||||
/// </summary>
|
||||
/// <param name="item">项</param>
|
||||
/// <returns>包含为 <see langword="true"/> 不包含为 <see langword="false"/></returns>
|
||||
public bool Contains(ObservableValue<T> item)
|
||||
{
|
||||
return _bindingValues.ContainsKey(item.Guid);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerator<ObservableValue<T>?> GetEnumerator()
|
||||
{
|
||||
return _bindingValues.Values
|
||||
.Select(v => v.TryGetTarget(out var t) ? t : null)
|
||||
.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _onChange = false;
|
||||
|
||||
private void Item_ValueChanged(T oldValue, T newValue)
|
||||
{
|
||||
if (_onChange)
|
||||
return;
|
||||
_onChange = true;
|
||||
foreach (var bindingValue in _bindingValues.AsEnumerable())
|
||||
{
|
||||
if (bindingValue.Value.TryGetTarget(out var target))
|
||||
target.Value = newValue;
|
||||
else
|
||||
_bindingValues.Remove(bindingValue.Key);
|
||||
}
|
||||
_onChange = false;
|
||||
}
|
||||
}
|
204
VPet.ModMaker/SimpleObservable/ObservableValueT.cs
Normal file
204
VPet.ModMaker/SimpleObservable/ObservableValueT.cs
Normal file
@ -0,0 +1,204 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HKW.HKWViewModels.SimpleObservable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("\\{ObservableValue, Value = {Value}\\}")]
|
||||
public class ObservableValue<T> : ObservableValue, IEquatable<ObservableValue<T>>
|
||||
{
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private T _value = default!;
|
||||
|
||||
/// <inheritdoc cref=" ObservableValue.Value"/>
|
||||
public new T Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
if (_value?.Equals(value) is true)
|
||||
return;
|
||||
var oldValue = _value;
|
||||
if (NotifyPropertyChanging(oldValue, value))
|
||||
return;
|
||||
_value = value;
|
||||
NotifyPropertyChanged(oldValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分组
|
||||
/// </summary>
|
||||
public ObservableValueGroup<T>? Group { get; internal set; }
|
||||
|
||||
#region Ctor
|
||||
/// <inheritdoc/>
|
||||
public ObservableValue() { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="value">初始值</param>
|
||||
public ObservableValue(T value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NotifyProperty
|
||||
/// <summary>
|
||||
/// 通知属性改变前
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <returns>取消改变</returns>
|
||||
private bool NotifyPropertyChanging(T oldValue, T newValue)
|
||||
{
|
||||
NotifyPropertyChanging();
|
||||
var cancel = false;
|
||||
// 若全部事件取消改变 则取消改变
|
||||
ValueChanging?.Invoke(oldValue, newValue, ref cancel);
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知属性改变后
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
private void NotifyPropertyChanged(T oldValue, T newValue)
|
||||
{
|
||||
base.NotifyPropertyChanged(oldValue!, newValue!);
|
||||
ValueChanged?.Invoke(oldValue, newValue);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NotifySender
|
||||
/// <summary>
|
||||
/// 通知发送者
|
||||
/// </summary>
|
||||
public new ICollection<ObservableValue<T>> NotifySenders => _notifySenders.Values;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private readonly Dictionary<Guid, ObservableValue<T>> _notifySenders = new();
|
||||
|
||||
/// <inheritdoc cref=" ObservableValue.AddNotifySender(ObservableValue[])"/>
|
||||
public void AddNotifySender(params ObservableValue<T>[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.PropertyChanged += NotifySenderPropertyChanged;
|
||||
_notifySenders.Add(item.Guid, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref=" ObservableValue.RemoveNotifySender(ObservableValue[])"/>
|
||||
public void RemoveNotifySender(params ObservableValue<T>[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.PropertyChanged -= NotifySenderPropertyChanged;
|
||||
_notifySenders.Remove(item.Guid);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref=" ObservableValue.ClearNotifySender"/>
|
||||
public new void ClearNotifySender()
|
||||
{
|
||||
foreach (var sender in _notifySenders.Values)
|
||||
sender.PropertyChanged -= NotifySenderPropertyChanged;
|
||||
_notifySenders.Clear();
|
||||
}
|
||||
|
||||
private void NotifySenderPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
NotifySenderPropertyChanged(this, sender);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return Value?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return Equals(obj as ObservableValue<T>);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value?.GetHashCode() ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableValue<T>? other)
|
||||
{
|
||||
return Guid.Equals(other?.Guid) is 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 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
|
||||
|
||||
#region Event
|
||||
/// <summary>
|
||||
/// 值改变前事件
|
||||
/// </summary>
|
||||
public event ValueChangingEventHandler? ValueChanging;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件
|
||||
/// </summary>
|
||||
public event ValueChangedEventHandler? ValueChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delegate
|
||||
/// <summary>
|
||||
/// 值改变事件
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <param name="cancel">取消</param>
|
||||
public delegate void ValueChangingEventHandler(T oldValue, T newValue, ref bool cancel);
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public delegate void ValueChangedEventHandler(T oldValue, T newValue);
|
||||
#endregion
|
||||
}
|
@ -126,6 +126,8 @@
|
||||
<Compile Include="Models\ModModel\WorkModel.cs" />
|
||||
<Compile Include="SimpleObservable\ObservableCommandT.cs" />
|
||||
<Compile Include="ModMakerStyles.cs" />
|
||||
<Compile Include="SimpleObservable\ObservableValueGroup.cs" />
|
||||
<Compile Include="SimpleObservable\ObservableValueT.cs" />
|
||||
<Compile Include="ViewModels\ModEdit\AddCultureWindowVM.cs" />
|
||||
<Compile Include="ViewModels\ModEdit\AnimeEdit\FoodAnimeEditWindowVM.cs" />
|
||||
<Compile Include="ViewModels\ModEdit\AnimeEdit\AnimeEditWindowVM.cs" />
|
||||
|
@ -8,7 +8,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:pu="https://opensource.panuon.com/wpf-ui"
|
||||
xmlns:vm="clr-namespace:VPet.ModMaker.ViewModels.ModEdit.I18nEdit"
|
||||
Title="I18nEditWindow"
|
||||
Title="{ll:Str 多语言编辑器}"
|
||||
Width="800"
|
||||
Height="450"
|
||||
d:DataContext="{d:DesignInstance Type=vm:I18nEditWindowVM}"
|
||||
@ -20,10 +20,20 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding Search.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 搜索}"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding Search.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<ComboBox
|
||||
Grid.Column="1"
|
||||
ItemsSource="{Binding SearchTargets}"
|
||||
SelectedItem="{Binding SearchTarget.Value}" />
|
||||
</Grid>
|
||||
<DataGrid
|
||||
x:Name="DataGrid_Datas"
|
||||
Grid.Row="1"
|
||||
|
@ -28,11 +28,25 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
ShowI18nDatas.Value = I18nDatas;
|
||||
}
|
||||
else
|
||||
else if (SearchTarget.Value == nameof(ModInfoModel.Id))
|
||||
{
|
||||
ShowI18nDatas.Value = new(
|
||||
I18nDatas.Where(
|
||||
m => m.Id.Value.Contains(newValue, StringComparison.OrdinalIgnoreCase)
|
||||
m => m.Id.Value?.Contains(newValue, StringComparison.OrdinalIgnoreCase) is true
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cultureIndex = I18nHelper.Current.CultureNames.IndexOf(SearchTarget.Value);
|
||||
ShowI18nDatas.Value = new(
|
||||
I18nDatas.Where(
|
||||
m =>
|
||||
m.Datas[cultureIndex].Value?.Contains(
|
||||
newValue,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
is true
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -66,6 +80,7 @@ public partial class I18nEditWindow : WindowX
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
AddCulture(culture);
|
||||
SearchTargets.Add(culture);
|
||||
}
|
||||
LoadFood(model);
|
||||
LoadClickText(model);
|
||||
@ -78,19 +93,54 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
foreach (var food in model.Foods)
|
||||
{
|
||||
var nameData = new I18nData();
|
||||
var descriptionData = new I18nData();
|
||||
nameData.Id.Value = food.Id.Value;
|
||||
descriptionData.Id.Value = food.DescriptionId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
if (AllData.TryGetValue(food.Id.Value, out var outData))
|
||||
{
|
||||
nameData.Cultures.Add(culture);
|
||||
nameData.Datas.Add(food.I18nDatas[culture].Name);
|
||||
descriptionData.Cultures.Add(culture);
|
||||
descriptionData.Datas.Add(food.I18nDatas[culture].Description);
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(food.I18nDatas[culture.Value].Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = food.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(food.I18nDatas[culture].Name);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(food.Id.Value, data);
|
||||
}
|
||||
if (AllData.TryGetValue(food.DescriptionId.Value, out var outData1))
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData1.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData1.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData1.Datas[culture.Index].Group!.Add(
|
||||
food.I18nDatas[culture.Value].Description
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = food.DescriptionId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(food.I18nDatas[culture].Description);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(food.DescriptionId.Value, data);
|
||||
}
|
||||
I18nDatas.Add(nameData);
|
||||
I18nDatas.Add(descriptionData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,14 +148,29 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
foreach (var text in model.ClickTexts)
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = text.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
if (AllData.TryGetValue(text.Id.Value, out var outData))
|
||||
{
|
||||
data.Cultures.Add(culture);
|
||||
data.Datas.Add(text.I18nDatas[culture].Text);
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(text.I18nDatas[culture.Value].Text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = text.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(text.I18nDatas[culture].Text);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(text.Id.Value, data);
|
||||
}
|
||||
I18nDatas.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,14 +178,29 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
foreach (var text in model.LowTexts)
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = text.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
if (AllData.TryGetValue(text.Id.Value, out var outData))
|
||||
{
|
||||
data.Cultures.Add(culture);
|
||||
data.Datas.Add(text.I18nDatas[culture].Text);
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(text.I18nDatas[culture.Value].Text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = text.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(text.I18nDatas[culture].Text);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(text.Id.Value, data);
|
||||
}
|
||||
I18nDatas.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,19 +208,52 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
foreach (var text in model.SelectTexts)
|
||||
{
|
||||
var data = new I18nData();
|
||||
var chooseData = new I18nData();
|
||||
data.Id.Value = text.Id.Value;
|
||||
chooseData.Id.Value = text.ChooseId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
if (AllData.TryGetValue(text.Id.Value, out var outData))
|
||||
{
|
||||
data.Cultures.Add(culture);
|
||||
data.Datas.Add(text.I18nDatas[culture].Text);
|
||||
chooseData.Cultures.Add(culture);
|
||||
chooseData.Datas.Add(text.I18nDatas[culture].Choose);
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(text.I18nDatas[culture.Value].Text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = text.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(text.I18nDatas[culture].Text);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(text.Id.Value, data);
|
||||
}
|
||||
if (AllData.TryGetValue(text.ChooseId.Value, out var outData1))
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData1.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData1.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData1.Datas[culture.Index].Group!.Add(text.I18nDatas[culture.Value].Choose);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = text.ChooseId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(text.I18nDatas[culture].Choose);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(text.ChooseId.Value, data);
|
||||
}
|
||||
I18nDatas.Add(data);
|
||||
I18nDatas.Add(chooseData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,32 +261,112 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
foreach (var pet in model.Pets)
|
||||
{
|
||||
var data = new I18nData();
|
||||
var petNameData = new I18nData();
|
||||
var descriptionData = new I18nData();
|
||||
data.Id.Value = pet.Id.Value;
|
||||
petNameData.Id.Value = pet.PetNameId.Value;
|
||||
descriptionData.Id.Value = pet.DescriptionId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
if (pet.IsSimplePetModel)
|
||||
continue;
|
||||
if (AllData.TryGetValue(pet.Id.Value, out var outData))
|
||||
{
|
||||
data.Cultures.Add(culture);
|
||||
data.Datas.Add(pet.I18nDatas[culture].Name);
|
||||
petNameData.Cultures.Add(culture);
|
||||
petNameData.Datas.Add(pet.I18nDatas[culture].PetName);
|
||||
descriptionData.Cultures.Add(culture);
|
||||
descriptionData.Datas.Add(pet.I18nDatas[culture].Description);
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(pet.I18nDatas[culture.Value].Name);
|
||||
}
|
||||
}
|
||||
I18nDatas.Add(data);
|
||||
I18nDatas.Add(petNameData);
|
||||
I18nDatas.Add(descriptionData);
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = pet.Id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(pet.I18nDatas[culture].Name);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(pet.Id.Value, data);
|
||||
}
|
||||
if (AllData.TryGetValue(pet.PetNameId.Value, out var outData1))
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData1.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData1.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData1.Datas[culture.Index].Group!.Add(pet.I18nDatas[culture.Value].PetName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = pet.PetNameId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(pet.I18nDatas[culture].PetName);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(pet.PetNameId.Value, data);
|
||||
}
|
||||
if (AllData.TryGetValue(pet.DescriptionId.Value, out var outData2))
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.Enumerate())
|
||||
{
|
||||
if (outData2.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>()
|
||||
{
|
||||
outData2.Datas[culture.Index]
|
||||
};
|
||||
}
|
||||
outData2.Datas[culture.Index].Group!.Add(
|
||||
pet.I18nDatas[culture.Value].Description
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = pet.DescriptionId.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(pet.I18nDatas[culture].Description);
|
||||
I18nDatas.Add(data);
|
||||
AllData.Add(pet.DescriptionId.Value, data);
|
||||
}
|
||||
//var data = new I18nData();
|
||||
//var petNameData = new I18nData();
|
||||
//var descriptionData = new I18nData();
|
||||
//data.Id.Value = pet.Id.Value;
|
||||
//petNameData.Id.Value = pet.PetNameId.Value;
|
||||
//descriptionData.Id.Value = pet.DescriptionId.Value;
|
||||
//foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
//{
|
||||
// data.Datas.Add(pet.I18nDatas[culture].Name);
|
||||
// petNameData.Datas.Add(pet.I18nDatas[culture].PetName);
|
||||
// descriptionData.Datas.Add(pet.I18nDatas[culture].Description);
|
||||
//}
|
||||
//I18nDatas.Add(data);
|
||||
//I18nDatas.Add(petNameData);
|
||||
//I18nDatas.Add(descriptionData);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, DataGridTextColumn> _dataGridI18nColumns = new();
|
||||
public HashSet<string> Ids { get; } = new();
|
||||
public Dictionary<string, I18nData> AllData { get; } = new();
|
||||
public ObservableCollection<I18nData> I18nDatas { get; } = new();
|
||||
public ObservableValue<ObservableCollection<I18nData>> ShowI18nDatas { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 搜索目标列表
|
||||
/// </summary>
|
||||
public ObservableCollection<string> SearchTargets { get; } = new() { nameof(ModInfoModel.Id) };
|
||||
|
||||
/// <summary>
|
||||
/// 搜索目标
|
||||
/// </summary>
|
||||
public ObservableValue<string> SearchTarget { get; } = new();
|
||||
|
||||
#region CultureEdit
|
||||
// TODO: 国际化标头
|
||||
private const string ValueBindingFormat = "Datas[{0}].Value";
|
||||
|
Loading…
Reference in New Issue
Block a user