diff --git a/VPet.ModMaker/SimpleObservable/ObservableValue.cs b/VPet.ModMaker/SimpleObservable/ObservableValue.cs index 34c754c..0e2e68e 100644 --- a/VPet.ModMaker/SimpleObservable/ObservableValue.cs +++ b/VPet.ModMaker/SimpleObservable/ObservableValue.cs @@ -1,36 +1,42 @@ 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; /// /// 可观察值 /// +/// [DebuggerDisplay("\\{ObservableValue, Value = {Value}\\}")] -public class ObservableValue +public class ObservableValue : INotifyPropertyChanging, INotifyPropertyChanged, - IEquatable + IEquatable> { [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private object _value = default!; + private T _value = default!; /// - /// 当前值 + /// 值 /// - public object Value + public T 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); } } @@ -39,6 +45,11 @@ public class ObservableValue /// public bool HasValue => Value != null; + /// + /// 分组 + /// + public ObservableValueGroup? Group { get; internal set; } + /// /// 唯一标识符 /// @@ -50,7 +61,7 @@ public class ObservableValue /// /// 初始值 - public ObservableValue(object value) + public ObservableValue(T value) { _value = value; } @@ -60,10 +71,16 @@ public class ObservableValue /// /// 通知属性改变前 /// + /// 旧值 + /// 新值 /// 取消改变 - protected void NotifyPropertyChanging() + private bool NotifyPropertyChanging(T oldValue, T newValue) { PropertyChanging?.Invoke(this, new(nameof(Value))); + var cancel = false; + // 若全部事件取消改变 则取消改变 + ValueChanging?.Invoke(oldValue, newValue, ref cancel); + return cancel; } /// @@ -71,11 +88,10 @@ public class ObservableValue /// /// 旧值 /// 新值 - protected void NotifyPropertyChanged(object oldValue, object newValue) + private void NotifyPropertyChanged(T oldValue, T newValue) { PropertyChanged?.Invoke(this, new(nameof(Value))); - if (oldValue is null || newValue is null) - PropertyChanged?.Invoke(this, new(nameof(HasValue))); + ValueChanged?.Invoke(oldValue, newValue); } #endregion @@ -83,10 +99,10 @@ public class ObservableValue /// /// 通知发送者 /// - public ICollection NotifySenders => _notifySenders.Values; + public IReadOnlyCollection NotifySenders => _notifySenders; [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private readonly Dictionary _notifySenders = new(); + private readonly HashSet _notifySenders = new(); /// /// 添加通知发送者 @@ -98,7 +114,7 @@ public class ObservableValue /// ObservableValue value1 = new(); /// ObservableValue value2 = new(); /// value2.AddNotifySender(value1); - /// value2.NotifyReceived += (source, sender) => + /// value2.SenderPropertyChanged += (source, sender) => /// { /// source.Value = sender.Value; /// }; @@ -108,27 +124,13 @@ public class ObservableValue /// /// /// 发送者 - public void AddNotifySender(params ObservableValue[] items) + public void AddNotifySender(params INotifyPropertyChanged[] items) { foreach (var item in items) { - item.PropertyChanged += Notify_SenderPropertyChanged; - _notifySenders.Add(item.Guid, item); - } - } - - /// - /// 添加通知发送者 - /// - /// 注: 此方法添加的发送者不会被记录到 中 - /// - /// - /// 发送者 - public void AddNotifySender(params INotifyPropertyChanged[] notices) - { - foreach (var item in notices) - { - item.PropertyChanged += Notify_SenderPropertyChanged; + item.PropertyChanged -= NotifySenderPropertyChanged; + item.PropertyChanged += NotifySenderPropertyChanged; + _notifySenders.Add(item); } } @@ -136,27 +138,12 @@ public class ObservableValue /// 删除通知发送者 /// /// 发送者 - public void RemoveNotifySender(params ObservableValue[] items) + public void RemoveNotifySender(params INotifyPropertyChanged[] items) { foreach (var item in items) { - item.PropertyChanged -= Notify_SenderPropertyChanged; - _notifySenders.Remove(item.Guid); - } - } - - /// - /// 删除通知发送者 - /// - /// 注: 此方法删除的发送者不会从 中删除 - /// - /// - /// 发送者 - public void RemoveNotifySender(params INotifyPropertyChanged[] notices) - { - foreach (var item in notices) - { - item.PropertyChanged -= Notify_SenderPropertyChanged; + item.PropertyChanged -= NotifySenderPropertyChanged; + _notifySenders.Remove(item); } } @@ -165,24 +152,14 @@ public class ObservableValue /// public void ClearNotifySender() { - foreach (var sender in _notifySenders.Values) - sender.PropertyChanged -= Notify_SenderPropertyChanged; + foreach (var sender in _notifySenders) + sender.PropertyChanged -= NotifySenderPropertyChanged; _notifySenders.Clear(); } - private void Notify_SenderPropertyChanged(object? sender, PropertyChangedEventArgs e) + private void NotifySenderPropertyChanged(object? sender, PropertyChangedEventArgs e) { - NotifySenderPropertyChanged(this, sender); - } - - /// - /// 通知接收事件 - /// - /// 源 - /// 发送者 - protected void NotifySenderPropertyChanged(ObservableValue source, object? sender) - { - SenderPropertyChanged?.Invoke(source, sender); + SenderPropertyChanged?.Invoke(this, (INotifyPropertyChanged)sender!); } #endregion @@ -196,17 +173,17 @@ public class ObservableValue /// public override bool Equals(object? obj) { - return Equals(obj as ObservableValue); + return Equals(obj as ObservableValue); } /// public override int GetHashCode() { - return Value?.GetHashCode() ?? 0; + return Guid.GetHashCode(); } /// - public bool Equals(ObservableValue? other) + public bool Equals(ObservableValue? other) { return Guid.Equals(other?.Guid) is true; } @@ -217,7 +194,7 @@ public class ObservableValue /// 左值 /// 右值 /// 相等为 否则为 - public static bool operator ==(ObservableValue value1, ObservableValue value2) + public static bool operator ==(ObservableValue value1, ObservableValue value2) { return value1.Value?.Equals(value2.Value) is true; } @@ -228,7 +205,7 @@ public class ObservableValue /// 左值 /// 右值 /// 不相等为 否则为 - public static bool operator !=(ObservableValue value1, ObservableValue value2) + public static bool operator !=(ObservableValue value1, ObservableValue value2) { return value1.Value?.Equals(value2.Value) is not true; } @@ -236,6 +213,7 @@ public class ObservableValue #endregion #region Event + /// /// 属性改变前事件 /// @@ -246,18 +224,47 @@ public class ObservableValue /// public event PropertyChangedEventHandler? PropertyChanged; + /// + /// 值改变前事件 + /// + public event ValueChangingEventHandler? ValueChanging; + + /// + /// 值改变后事件 + /// + public event ValueChangedEventHandler? ValueChanged; + /// /// 通知接收事件 /// public event NotifySenderPropertyChangedHandler? SenderPropertyChanged; + #endregion #region Delegate + /// + /// 值改变事件 + /// + /// 旧值 + /// 新值 + /// 取消 + public delegate void ValueChangingEventHandler(T oldValue, T newValue, ref bool cancel); + + /// + /// 值改变后事件 + /// + /// 旧值 + /// 新值 + public delegate void ValueChangedEventHandler(T oldValue, T newValue); + /// /// 通知发送者属性改变接收器 /// /// 源 /// 发送者 - public delegate void NotifySenderPropertyChangedHandler(ObservableValue source, object? sender); + public delegate void NotifySenderPropertyChangedHandler( + ObservableValue source, + INotifyPropertyChanged? sender + ); #endregion } diff --git a/VPet.ModMaker/SimpleObservable/ObservableValueGroup.cs b/VPet.ModMaker/SimpleObservable/ObservableValueGroup.cs index 105c4f9..a12e104 100644 --- a/VPet.ModMaker/SimpleObservable/ObservableValueGroup.cs +++ b/VPet.ModMaker/SimpleObservable/ObservableValueGroup.cs @@ -46,10 +46,10 @@ public class ObservableValueGroup : IEnumerable?> public void Add(params ObservableValue[] items) { foreach (var item in items) - AddX(item); + AddToGroup(item); } - private void AddX(ObservableValue item) + private void AddToGroup(ObservableValue item) { if (item.Group is not null) throw new ArgumentException("item.Group must be null", nameof(item)); @@ -77,10 +77,10 @@ public class ObservableValueGroup : IEnumerable?> public void Remove(params ObservableValue[] items) { foreach (var item in items) - RemoveX(item); + RemoveFromGroup(item); } - private void RemoveX(ObservableValue item) + private void RemoveFromGroup(ObservableValue item) { var result = _bindingValues.Remove(item.Guid); if (result) diff --git a/VPet.ModMaker/SimpleObservable/ObservableValueT.cs b/VPet.ModMaker/SimpleObservable/ObservableValueT.cs deleted file mode 100644 index a6ddf14..0000000 --- a/VPet.ModMaker/SimpleObservable/ObservableValueT.cs +++ /dev/null @@ -1,204 +0,0 @@ -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; - -/// -/// 可观察值 -/// -/// -[DebuggerDisplay("\\{ObservableValue, Value = {Value}\\}")] -public class ObservableValue : ObservableValue, IEquatable> -{ - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private T _value = default!; - - /// - 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); - } - } - - /// - /// 分组 - /// - public ObservableValueGroup? Group { get; internal set; } - - #region Ctor - /// - public ObservableValue() { } - - /// - /// 初始值 - public ObservableValue(T value) - { - _value = value; - } - #endregion - - #region NotifyProperty - /// - /// 通知属性改变前 - /// - /// 旧值 - /// 新值 - /// 取消改变 - private bool NotifyPropertyChanging(T oldValue, T newValue) - { - NotifyPropertyChanging(); - var cancel = false; - // 若全部事件取消改变 则取消改变 - ValueChanging?.Invoke(oldValue, newValue, ref cancel); - return cancel; - } - - /// - /// 通知属性改变后 - /// - /// 旧值 - /// 新值 - private void NotifyPropertyChanged(T oldValue, T newValue) - { - base.NotifyPropertyChanged(oldValue!, newValue!); - ValueChanged?.Invoke(oldValue, newValue); - } - #endregion - - #region NotifySender - /// - /// 通知发送者 - /// - public new ICollection> NotifySenders => _notifySenders.Values; - - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private readonly Dictionary> _notifySenders = new(); - - /// - public void AddNotifySender(params ObservableValue[] items) - { - foreach (var item in items) - { - item.PropertyChanged += NotifySenderPropertyChanged; - _notifySenders.Add(item.Guid, item); - } - } - - /// - public void RemoveNotifySender(params ObservableValue[] items) - { - foreach (var item in items) - { - item.PropertyChanged -= NotifySenderPropertyChanged; - _notifySenders.Remove(item.Guid); - } - } - - /// - 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 - /// - public override string ToString() - { - return Value?.ToString() ?? string.Empty; - } - - /// - public override bool Equals(object? obj) - { - return Equals(obj as ObservableValue); - } - - /// - public override int GetHashCode() - { - return Value?.GetHashCode() ?? 0; - } - - /// - public bool Equals(ObservableValue? other) - { - return Guid.Equals(other?.Guid) is true; - } - - /// - /// 判断 相等 - /// - /// 左值 - /// 右值 - /// 相等为 否则为 - public static bool operator ==(ObservableValue value1, ObservableValue value2) - { - return value1.Value?.Equals(value2.Value) is true; - } - - /// - /// 判断 不相等 - /// - /// 左值 - /// 右值 - /// 不相等为 否则为 - public static bool operator !=(ObservableValue value1, ObservableValue value2) - { - return value1.Value?.Equals(value2.Value) is not true; - } - - #endregion - - #region Event - /// - /// 值改变前事件 - /// - public event ValueChangingEventHandler? ValueChanging; - - /// - /// 值改变后事件 - /// - public event ValueChangedEventHandler? ValueChanged; - - #endregion - - #region Delegate - /// - /// 值改变事件 - /// - /// 旧值 - /// 新值 - /// 取消 - public delegate void ValueChangingEventHandler(T oldValue, T newValue, ref bool cancel); - - /// - /// 值改变后事件 - /// - /// 旧值 - /// 新值 - public delegate void ValueChangedEventHandler(T oldValue, T newValue); - #endregion -} diff --git a/VPet.ModMaker/Styles.xaml b/VPet.ModMaker/Styles.xaml index 7883356..db4084f 100644 --- a/VPet.ModMaker/Styles.xaml +++ b/VPet.ModMaker/Styles.xaml @@ -13,6 +13,13 @@ +