/// <summary> /// 内部赋值 /// </summary> /// <param name="p_val"></param> /// <param name="p_checkChange">是否逐级检查IsChanged状态</param> /// <param name="p_isBinding">是否为绑定状态</param> void SetValueInternal(object p_val, bool p_checkChange, bool p_isBinding) { // 过滤多次赋值现象,当cell的类型为string时,在给val赋值null时,将一直保持初始的string.Empty的值 if (object.Equals(_val, p_val) || (Type == typeof(string) && (string)_val == string.Empty && p_val == null)) { return; } // 类型不同时转换 object val = GetValInternal(p_val, Type); // 外部钩子通常为业务校验、领域事件等,校验失败时触发异常使赋值失败 if (Hook != null) { #if SERVER // 服务端无绑定 Hook.Invoke(Row, new object[] { val }); #else if (!p_isBinding) { // 无绑定时不catch钩子抛出的异常,统一在未处理异常中提示警告信息 Hook.Invoke(Row, new object[] { val }); } else { try { // 绑定时钩子抛出的异常被UWP内部catch,无法统一提示警告信息,故先catch Hook.Invoke(Row, new object[] { p_val }); } catch (Exception ex) { if (ex.InnerException is KnownException kex) { Kit.Warn(kex.Message); } else { Kit.Warn(ex.Message); } // 通知UI重置原值 if (PropertyChanged != null) { #if !UWP // uno变态,必须完整执行一遍赋值,触发两次属性值变化,否则UI不重置!!!浪费半天 var old = OriginalVal; OriginalVal = _val; _val = p_val; PropertyChanged(this, new PropertyChangedEventArgs("Val")); _val = OriginalVal; OriginalVal = old; #endif // 立即调用时无效! Kit.RunAsync(() => PropertyChanged(this, new PropertyChangedEventArgs("Val"))); } // 直接返回,赋值失败 return; } } #endif } // 成功赋值 _val = val; // 向上逐级更新IsChanged状态 if (p_checkChange) { IsChanged = !object.Equals(_val, OriginalVal); } // 触发属性变化事件 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Val")); // 数据项值改变时统一在Table和Row中触发事件 Row.OnValueChanged(this); if (Row.Table != null) { Row.Table.OnValueChanged(this); } }