Esempio n. 1
0
        //protected void LoadRefProperty(IRefIdProperty refProperty)
        //{
        //    //暂时只是获取 Entity,以后可以使用其它方法优化此实现。
        //    var load = this.GetLazyRef(refProperty).Entity;
        //}

        /// <summary>
        /// 设置指定属性的值。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="value"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        public override object SetProperty(IManagedProperty property, object value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
        {
            //防止外界使用 SetProperty 方法来操作引用属性。
            if (property is IRefProperty)
            {
                if (property is IRefIdProperty)
                {
                    return(this.SetRefId(property as IRefIdProperty, value, source));
                }
                else
                {
                    return(this.SetRefEntity(property as IRefEntityProperty, value as Entity, source));
                }
            }
            //防止外界使用 SetProperty 方法来操作列表属性。
            else if (property is IListProperty)
            {
                throw new InvalidOperationException(string.Format("{0} 是列表属性,不能使用 SetProperty 方法直接设置。请使用 GetLazyList 方法获取,或使用 LoadProperty 方法进行加载。", property));
            }
            else if (property == IdProperty || property == TreePIdProperty && value != null)
            {
                //由于 Id 属性的托管属性类型是 object,这里需要强制为具体的主键类型。
                value = TypeHelper.CoerceValue(this.IdProvider.KeyType, value);
            }

            return(base.SetProperty(property, value, source));
        }
 public ManagedPropertyChangedEventArgs(IManagedProperty property, object oldValue, object newValue, ManagedPropertyChangedSource source)
 {
     this._property = property;
     this._oldValue = oldValue;
     this._newValue = newValue;
     this._source   = source;
 }
 public ManagedPropertyChangedEventArgs(IManagedProperty property, object oldValue, object newValue, ManagedPropertyChangedSource source)
 {
     this._property = property;
     this._oldValue = oldValue;
     this._newValue = newValue;
     this._source = source;
 }
Esempio n. 4
0
        /// <summary>
        /// 设置指定引用 id 属性对应的 id 的可空类型值。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="value">本方法为兼容值类型而使用。不论外键是否为值类型,都可以传入 null。</param>
        /// <param name="source"></param>
        /// <returns></returns>
        public object SetRefNullableId(IRefIdProperty property, object value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
        {
            if (value == null)
            {
                value = GetEmptyIdForRefIdProperty(property);
            }
            var finalValue = this.SetRefId(property, value, source);

            return(property.KeyProvider.ToNullableValue(finalValue));
        }
Esempio n. 5
0
        /// <summary>
        /// 向子类公布一个方法,这样子类可以使用 IManagedProperty 来进行属性变更通知。
        /// 注意,这个方法发布的事件,NewValue、OldValue 将不可用。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="source"></param>
        public void NotifyPropertyChanged(IManagedProperty property, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
        {
            var propertyInternal = property as IManagedPropertyInternal;

            if (property.IsReadOnly)
            {
                propertyInternal.RaiseReadOnlyPropertyChanged(this, source);
            }
            else
            {
                var defaultValue = property.GetMeta(this).DefaultValue;
                var args         = new ManagedPropertyChangedEventArgs(property, defaultValue, defaultValue, source);
                this.RaisePropertyChanged(args);
            }
        }
Esempio n. 6
0
        bool IManagedPropertyMetadataInternal.RaisePropertyChangingMetaEvent(
            ManagedPropertyObject sender, ref object value, ManagedPropertyChangedSource source
            )
        {
            if (this._propertyChangingCallBack != null)
            {
                var e = new ManagedPropertyChangingEventArgs <TPropertyType>(this._property, (TPropertyType)value, source);

                this._propertyChangingCallBack(sender, e);

                if (e.HasCoercedValue)
                {
                    value = e.CoercedValue;
                }

                return(e.Cancel);
            }

            return(false);
        }
Esempio n. 7
0
        void IManagedPropertyInternal.RaiseReadOnlyPropertyChanged(ManagedPropertyObject sender, ManagedPropertyChangedSource source)
        {
            //直接装箱,以免下行代码装箱两次。
            object nonValue = default(TPropertyType);

            sender.RaisePropertyChanged(new ManagedPropertyChangedEventArgs(this, nonValue, nonValue, source));
        }
Esempio n. 8
0
 /// <summary>
 /// 设置 LOB 属性的值。
 /// </summary>
 /// <param name="property"></param>
 /// <param name="value"></param>
 /// <param name="source"></param>
 public void SetLOBProperty(ILOBProperty property, object value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
 {
     //直接调用父类的 SetProperty 方法,而不是本类重写的 SetProperty 方法。
     base.SetProperty(property, value, source);
 }
Esempio n. 9
0
        /// <summary>
        /// 设置指定引用实体属性的值。
        /// 在实体属性变化时,会同步相应的引用 Id 属性。
        /// </summary>
        /// <param name="entityProperty">The entity property.</param>
        /// <param name="value">The value.</param>
        /// <param name="source">The source.</param>
        /// <returns></returns>
        public Entity SetRefEntity(IRefEntityProperty entityProperty, Entity value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
        {
            var    oldEntity   = base.GetProperty(entityProperty) as Entity;
            Entity finalEntity = oldEntity;

            try
            {
                _settingEntity = true;

                var idProperty = entityProperty.RefIdProperty;
                var oldId      = this.GetProperty(idProperty);

                //如果 实体变更 或者 (设置实体为 null 并且 id 不为 null),都需要设置值改变。
                if (oldEntity != value || (value == null && HasRefId(idProperty, oldId)))
                {
                    var newId = value == null?GetEmptyIdForRefIdProperty(idProperty) : value.Id;

                    //在触发外界事件处理函数之前,先设置好 Id 的值
                    base.LoadProperty(idProperty, newId);
                    try
                    {
                        //此时再发生 OnEntityChanged 事件,外界可以获取到一致的 id 和 entity 值。
                        finalEntity = base.SetProperty(entityProperty, value, source) as Entity;
                    }
                    finally
                    {
                        //还原 id 的值。
                        base.LoadProperty(idProperty, oldId);
                    }

                    //如果设置实体成功,则需要开始变更 Id 的值。
                    if (finalEntity == value)
                    {
                        //如果 id 发生了变化,则需要设置 id 的值。
                        if (!object.Equals(oldId, newId))
                        {
                            //尝试设置 id 值,如果成功,则同时会发生 OnIdChanged 事件。
                            var finalId = base.SetProperty(idProperty, newId, source);

                            //如果设置 id 值失败,则应该还原 entity 的值。
                            if (!object.Equals(finalId, newId))
                            {
                                finalEntity = base.SetProperty(entityProperty, oldEntity, source) as Entity;

                                //还原 entity 值失败,向个界抛出冲突的异常。
                                if (finalEntity != oldEntity)
                                {
                                    ThrowRefPropertyChangingConflict(idProperty);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                _settingEntity = false;
            }

            return(finalEntity);
        }
Esempio n. 10
0
        /// <summary>
        /// 设置指定引用 id 属性对应的 id 的值。
        ///
        /// 在引用 id 变化时,会同步相应的引用实体属性。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="value">外键如果是值类型,则不能传入 null。</param>
        /// <param name="source"></param>
        /// <returns></returns>
        public object SetRefId(IRefIdProperty property, object value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
        {
            //引用属性的托管属性类型是 object,这里需要强制为指定的主键类型。
            value = TypeHelper.CoerceValue(property.KeyProvider.KeyType, value);

            var id = this.GetRefId(property);

            //设置 id 完成后的值。
            object finalId = id;

            //确实需要改变 Id 时,才进行以下逻辑。
            if (!object.Equals(id, value))
            {
                var entityProperty = property.RefEntityProperty;

                //在设置 RefId 前先清空实体值,这样在回调 RefId 的外部 Changed 事件处理函数时,
                //外部看到的 RefEntity 也已经改变了,外部可以获得一致的 Entity 和 Id 值。
                var entity = base.GetProperty(entityProperty) as Entity;
                if (entity != null && !object.Equals(entity.Id, value))
                {
                    base.ResetProperty(entityProperty);
                }
                try
                {
                    //此时发生 OnIdChanged 事件。
                    finalId = base.SetProperty(property, value, source);
                }
                finally
                {
                    //还原实体的值。
                    if (entity != null)
                    {
                        base.LoadProperty(entityProperty, entity);
                    }
                }

                //如果二者相等,表示 Id 成功设置,没有被 cancel。
                if (object.Equals(finalId, value))
                {
                    //如果之前的实体已经存在值,则需要设置为 null,并引发外部事件。
                    if (entity != null)
                    {
                        //重新设置 Entity 的值,此时发生 OnEntityChanged 事件。
                        var finalEntity = base.SetProperty(entityProperty, null, source) as Entity;

                        //如果外部事件取消了属性的设置,那么实际使用的实体将不会为 null,
                        if (finalEntity != null)
                        {
                            //此时,需要重设 Id 的值。
                            finalId = base.SetProperty(property, finalEntity.Id, source);
                            if (!object.Equals(finalId, finalEntity.Id))
                            {
                                ThrowRefPropertyChangingConflict(property);
                            }
                        }
                    }
                }
            }

            return(finalId);
        }
Esempio n. 11
0
 /// <summary>
 /// 设置某个托管属性的值。
 /// </summary>
 /// <param name="property"></param>
 /// <param name="value"></param>
 /// <param name="source">本次值设置的来源。</param>
 /// <returns>返回最终使用的值。</returns>
 public virtual object SetProperty(IManagedProperty property, object value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
 {
     return(this._SetProperty(property, value, source));
 }
Esempio n. 12
0
 /// <summary>
 /// 设置某个 bool 类型托管属性的值。
 /// </summary>
 /// <param name="property"></param>
 /// <param name="value"></param>
 /// <param name="source">本次值设置的来源。</param>
 /// <returns>返回最终使用的值。</returns>
 public object SetProperty(ManagedProperty <bool> property, bool value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty)
 {
     //使用 BooleanBoxes 来防止装箱操作。
     return(this._SetProperty(property, BooleanBoxes.Box(value), source));
 }
Esempio n. 13
0
        /// <summary>
        /// 设置某个属性的值。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="value"></param>
        /// <param name="source"></param>
        /// <returns>返回最终使用的值。</returns>
        private object _SetProperty(IManagedProperty property, object value, ManagedPropertyChangedSource source)
        {
            object finalValue = null;

            CheckEditing(property);

            var meta = property.GetMeta(this) as IManagedPropertyMetadataInternal;

            finalValue = meta.DefaultValue;

            value = CoerceType(property, value);

            bool isReset = false;

            if (NeedReset(property, value))
            {
                isReset = true;
                value   = meta.DefaultValue;
            }

            bool cancel = meta.RaisePropertyChangingMetaEvent(this, ref value, source);

            if (!cancel)
            {
                bool   hasOldValue = false;
                object oldValue    = null;

                //这个 if 块中的代码:查找或创建对应 property 的 field,同时记录可能存在的历史值。
                if (property.LifeCycle == ManagedPropertyLifeCycle.Compile)
                {
                    var index = property.TypeCompiledIndex;
                    var field = this._compiledFields[index];
                    if (field.HasValue)
                    {
                        oldValue    = field.Value;
                        hasOldValue = true;
                    }

                    if (isReset)
                    {
                        this._compiledFields[index].ResetValue();
                    }
                    else
                    {
                        this._compiledFields[index]._value = value;
                    }
                }
                else
                {
                    if (this._runtimeFields == null)
                    {
                        if (!isReset)
                        {
                            this._runtimeFields = new Dictionary <IManagedProperty, ManagedPropertyField>();
                        }
                    }
                    else
                    {
                        var oldField = new ManagedPropertyField();
                        if (this._runtimeFields.TryGetValue(property, out oldField))
                        {
                            oldValue    = oldField.Value;
                            hasOldValue = true;
                        }
                    }

                    if (isReset)
                    {
                        if (hasOldValue)
                        {
                            this._runtimeFields.Remove(property);
                        }
                    }
                    else
                    {
                        //使用新的 field
                        var field = new ManagedPropertyField
                        {
                            _property = property,
                            _value    = value
                        };
                        if (hasOldValue)
                        {
                            this._runtimeFields[property] = field;
                        }
                        else
                        {
                            this._runtimeFields.Add(property, field);
                        }
                    }
                }

                if (!hasOldValue)
                {
                    oldValue = meta.DefaultValue;
                }

                if (!object.Equals(oldValue, value))
                {
                    var args = new ManagedPropertyChangedEventArgs(property, oldValue, value, source);

                    //发生 Meta 中的回调事件
                    meta.RaisePropertyChangedMetaEvent(this, args);

                    //发生外部事件
                    this.RaisePropertyChanged(args);

                    finalValue = value;
                }
            }

            return(finalValue);
        }
 public ManagedPropertyChangingEventArgs(IManagedProperty property, TPropertyType value, ManagedPropertyChangedSource source)
 {
     this._property = property;
     this._source   = source;
     this._value    = value;
 }
Esempio n. 15
0
 public void SetValue(object component, object value, ManagedPropertyChangedSource source)
 {
     (component as ManagedPropertyObject).SetProperty(this._property, value, source);
 }
Esempio n. 16
0
 public void SetValue(object component, object value, ManagedPropertyChangedSource source)
 {
     (component as ManagedPropertyObject).SetProperty(this._property, value, source);
 }