Example #1
0
File: Cell.cs Project: Daoting/dt
        /// <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);
            }
        }