using GFramework.Core.Abstractions.events; using GFramework.Core.Abstractions.property; namespace GFramework.Core.property; /// /// 可绑定属性类,用于实现数据绑定功能 /// /// 属性值的类型 /// 属性的默认值 public class BindableProperty(T defaultValue = default!) : IBindableProperty { private Action? _mOnValueChanged; protected T MValue = defaultValue; /// /// 获取或设置属性值比较器,默认使用Equals方法进行比较 /// public static Func Comparer { get; set; } = (a, b) => a!.Equals(b); /// /// 获取或设置属性值,当值发生变化时会触发注册的回调事件 /// public T Value { get => GetValue(); set { // 使用 default(T) 替代 null 比较,避免 SonarQube 警告 if (EqualityComparer.Default.Equals(value, default!) && EqualityComparer.Default.Equals(MValue, default!)) return; // 若新值与旧值相等则不执行后续操作 if (!EqualityComparer.Default.Equals(value, default!) && Comparer(value, MValue)) return; SetValue(value); _mOnValueChanged?.Invoke(value); } } /// /// 直接设置属性值而不触发事件 /// /// 新的属性值 public void SetValueWithoutEvent(T newValue) { MValue = newValue; } /// /// 实现IEasyEvent接口的注册方法,将无参事件转换为有参事件处理 /// /// 无参事件回调 /// 可用于取消注册的接口 IUnRegister IEasyEvent.Register(Action onEvent) { return Register(Action); void Action(T _) { onEvent(); } } /// /// 注册属性值变化事件回调 /// /// 属性值变化时的回调函数 /// 可用于取消注册的接口 public IUnRegister Register(Action onValueChanged) { _mOnValueChanged += onValueChanged; return new BindablePropertyUnRegister(this, onValueChanged); } /// /// 注册属性值变化事件回调,并立即调用回调函数传递当前值 /// /// 属性值变化时的回调函数 /// 可用于取消注册的接口 public IUnRegister RegisterWithInitValue(Action action) { action(MValue); return Register(action); } /// /// 取消注册属性值变化事件回调 /// /// 要取消注册的回调函数 public void UnRegister(Action onValueChanged) { _mOnValueChanged -= onValueChanged; } /// /// 设置自定义比较器 /// /// 用于比较两个值是否相等的函数 /// 当前可绑定属性实例 public BindableProperty WithComparer(Func comparer) { Comparer = comparer; return this; } /// /// 设置属性值的虚方法,可在子类中重写 /// /// 新的属性值 protected virtual void SetValue(T newValue) { MValue = newValue; } /// /// 获取属性值的虚方法,可在子类中重写 /// /// 当前属性值 protected virtual T GetValue() { return MValue; } /// /// 返回属性值的字符串表示形式 /// /// 属性值的字符串表示 public override string ToString() { return Value?.ToString() ?? string.Empty; } }