// TODO: Implement Create Collection With No Value. public override ICProp <CT, T> CreateWithNoValue <CT, T>( PropNameType propertyName, object extraInfo = null, PropStorageStrategyEnum storageStrategy = PropStorageStrategyEnum.Internal, bool typeIsSolid = true, Func <CT, CT, bool> comparer = null) { throw new NotImplementedException("PropExtStoreFactory has not implemented the Create Collection Prop with No Value."); }
//public virtual IProp CreateGenFromString(Type typeOfThisProperty, // string value, bool useDefault, // PropNameType propertyName, object extraInfo, // PropStorageStrategyEnum storageStrategy, bool isTypeSolid, PropKindEnum propKind, // Delegate comparer, bool useRefEquality = false, Type itemType = null) //{ // MemConsumptionTracker mct = new MemConsumptionTracker(enabled: false); // if (propKind == PropKindEnum.Prop) // { // CreateScalarProp propCreator = GetPropCreator(typeOfThisProperty); // mct.MeasureAndReport("GetPropCreator", $"for {propertyName}"); // // TODO: This is where strings are parsed to create objects of type T. // // TODO: This needs more work, to say the least. // IProp prop = propCreator(this, haveValue: true, value: value, useDefault: useDefault, propertyName: propertyName, // extraInfo: extraInfo, storageStrategy: storageStrategy, isTypeSolid: isTypeSolid, // comparer: comparer, useRefEquality: useRefEquality, getDefaultValFunc: null); // mct.MeasureAndReport("Ran propCreator to get IProp", $"for {propertyName}"); // return prop; // } // else if (propKind.IsCollection()) // { // CreateCPropFromStringDelegate propCreator = GetCPropFromStringCreator(typeOfThisProperty, itemType); // mct.MeasureAndReport("GetCPropFromStringCreator", $"for {propertyName}"); // IProp prop = propCreator(this, value: value, useDefault: useDefault, propertyName: propertyName, // extraInfo: extraInfo, storageStrategy: storageStrategy, isTypeSolid: isTypeSolid, // comparer: comparer, useRefEquality: useRefEquality); // mct.MeasureAndReport("Ran GetCPropFromStringCreator to get IProp", $"for {propertyName}"); // return prop; // } // else // { // throw new InvalidOperationException($"PropKind = {propKind} is not recognized or is not supported."); // } //} public virtual IProp CreateGenWithNoValue(Type typeOfThisProperty, PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool isTypeSolid, PropKindEnum propKind, Delegate comparer, bool useRefEquality = false, Type itemType = null) { MemConsumptionTracker mct = new MemConsumptionTracker(enabled: false); if (propKind == PropKindEnum.Prop) { CreateScalarProp propCreator = GetPropCreator(typeOfThisProperty); mct.MeasureAndReport("GetPropCreator", $"for {propertyName}"); IProp prop = propCreator(this, haveValue: false, value: null, useDefault: false, propertyName: propertyName, extraInfo: extraInfo, storageStrategy: storageStrategy, isTypeSolid: isTypeSolid, comparer: comparer, useRefEquality: useRefEquality, getDefaultValFunc: null); mct.MeasureAndReport("Ran propCreator to get IProp", $"for {propertyName}"); return(prop); } else if (propKind.IsCollection()) { CreateCPropWithNoValueDelegate propCreator = GetCPropWithNoValueCreator(typeOfThisProperty, itemType); IProp prop = propCreator(this, propertyName: propertyName, extraInfo: extraInfo, storageStrategy: storageStrategy, isTypeSolid: isTypeSolid, comparer: comparer, useRefEquality: useRefEquality); return(prop); } else { throw new InvalidOperationException($"PropKind = {propKind} is not recognized or is not supported."); } }
private bool UpdateTargetWithStartingValue(WeakRefKey <IPropBag> bindingTarget, PropNode sourcePropNode) { IProp typedProp = sourcePropNode.PropData_Internal.TypedProp; PropStorageStrategyEnum ss = typedProp.PropTemplate.StorageStrategy; switch (ss) { case PropStorageStrategyEnum.Internal: { T newValue = (T)typedProp.TypedValueAsObject; bool result = UpdateTarget(bindingTarget, newValue); return(result); } case PropStorageStrategyEnum.External: goto case PropStorageStrategyEnum.Internal; // This property has no backing store, there is no concept of a starting value. case PropStorageStrategyEnum.Virtual: return(false); default: throw new InvalidOperationException($"{ss} is not a recognized or supported Prop Storage Strategy when used as a source for a local binding."); } }
//Lazy<IValueConverter> _defaultConverter; //public virtual Lazy<IValueConverter> DefaultConverter //{ // get // { // if(_defaultConverter == null) // { // return new Lazy<IValueConverter>(() => new PropValueConverter()); // } // return _defaultConverter; // } // set // { // _defaultConverter = value; // } //} //Func<BindingTarget, MyBindingInfo, Type, string, object> _defConvParamBuilder; //public virtual Func<BindingTarget, MyBindingInfo, Type, string, object> DefaultConverterParameterBuilder //{ // get // { // if (_defConvParamBuilder == null) // { // return OurDefaultConverterParameterBuilder; // } // return _defConvParamBuilder; // } // set // { // _defConvParamBuilder = value; // } //} #endregion #region Constructor internal LocalBinder(PSAccessServiceInterface propStoreAccessService, LocalBindingInfo bindingInfo, IReceivePropStoreNodeUpdates storeNodeUpdateReceiver) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInterface>(propStoreAccessService); _bindingInfo = bindingInfo; _storeNodeUpdateReceiver = storeNodeUpdateReceiver; _bindingTarget = new SimpleExKey(); // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. // TODO: Instead of doing this now, create a property that allows us to access upon first access. _ourNode = GetPropBagNode(propStoreAccessService); _targetObject = null; _propertyName = null; _targetHasStore = PropStorageStrategyEnum.Virtual; _pathElements = GetPathElements(_bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } _pathListeners = new OSCollection <T>(); _isComplete = StartBinding(_targetObject, _pathElements, _pathListeners, _isPathAbsolute); }
// Complete public PropItemModel ( Type type, string name, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, PropKindEnum propKind, ITypeInfoField propTypeInfoField, IPropInitialValueField initialValueField, object extraInfo, IPropComparerField comparer, Type itemType, IPropBinderField binderField, IMapperRequest mapperRequest, PropCreatorType propCreator ) { PropertyType = type; PropertyName = name; ExtraInfo = extraInfo; StorageStrategy = storageStrategy; TypeIsSolid = typeIsSolid; PropKind = propKind; PropTypeInfoField = _propTypeInfoField; InitialValueField = initialValueField; ComparerField = comparer; _itemType = itemType; _propBinderField = binderField; _mapperRequest = mapperRequest; _propCreator = propCreator; InitialValueCooked = null; }
// With No Value private static ICProp <CT, T> CreateCPropWithNoValue <CT, T>(IPropFactory propFactory, bool useDefault, PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool isTypeSolid, Delegate comparer, bool useRefEquality = true) where CT : class, IReadOnlyList <T>, IList <T>, IEnumerable <T>, IList, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged { return(propFactory.CreateWithNoValue <CT, T>(propertyName, extraInfo, storageStrategy, isTypeSolid, GetComparerForCollections <CT>(comparer, propFactory, useRefEquality))); }
// TODO: Implement Create Collection With Initial Value. public override ICProp <CT, T> Create <CT, T>( CT initialValue, PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <CT, CT, bool> comparer) { throw new NotImplementedException("PropExtStoreFactory has not implemented the Create Collection Prop with Initial Value."); }
public abstract IProp <T> CreateWithNoValue <T> ( PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <T, T, bool> comparer, bool comparerIsRefEquality, Func <string, T> getDefaultValFunc );
// From Object private static ICProp <CT, T> CreateCPropFromObject <CT, T>(IPropFactory propFactory, object value, string propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool isTypeSolid, Delegate comparer, bool useRefEquality = false) where CT : class, IReadOnlyList <T>, IList <T>, IEnumerable <T>, IList, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged { CT initialValue = propFactory.GetValueFromObject <CT>(value); return(propFactory.Create <CT, T>(initialValue, propertyName, extraInfo, storageStrategy, isTypeSolid, GetComparerForCollections <CT>(comparer, propFactory, useRefEquality))); }
//public override ClrMappedDSP<TDestination> CreateMappedDS<TSource, TDestination>(uint propId, PropKindEnum propKind, IDoCRUD<TSource> dal, IPropStoreAccessService<uint, string> storeAccesor, IPropBagMapper<TSource, TDestination> mapper) //{ // throw new NotImplementedException(); //} #endregion #region Scalar Prop Creation public override IProp <T> Create <T>( T initialValue, PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <T, T, bool> comparer, bool comparerIsRefEquality, Func <string, T> getDefaultValFunc) { throw new InvalidOperationException("External Store Factory doesn't know how to create properties with initial values."); }
public XMLPropItemModel(string type, string name, string extraInfo = null, PropStorageStrategyEnum storageStrategy = PropStorageStrategyEnum.Internal, bool typeIsSolid = true, PropDoWhenChanged doWhenChanged = null, PropComparerField comparer = null) { Type = type; Name = name; ExtraInfo = extraInfo; StorageStrategy = storageStrategy; TypeIsSolid = typeIsSolid; ComparerField = comparer; DoWhenChangedField = doWhenChanged; }
protected virtual IPropTemplate <T> GetPropTemplate <T> ( PropKindEnum propKindEnum, PropStorageStrategyEnum storageStrategy, Func <T, T, bool> comparer, bool comparerIsRefEquality, Func <string, T> getDefaultVal ) { // Supply a comparer, if one was not supplied by the caller. bool comparerIsDefault; if (comparer == null) { comparer = EqualityComparer <T> .Default.Equals; comparerIsDefault = true; } else { comparerIsDefault = false; } bool defaultValFuncIsDefault; // Use the Get Default Value function supplied or provided by this Prop Factory. if (getDefaultVal == null) { getDefaultVal = ValueConverter.GetDefaultValue <T>; defaultValFuncIsDefault = true; } else { defaultValFuncIsDefault = false; } IPropTemplate <T> propTemplateTyped = new PropTemplateTyped <T> ( propKindEnum, storageStrategy, this.GetType(), comparerIsDefault, comparerIsRefEquality, comparer, getDefaultVal, defaultValFuncIsDefault ); IPropTemplate <T> existingEntry = (IPropTemplate <T>)DelegateCacheProvider.PropTemplateCache.GetOrAdd(propTemplateTyped); return(existingEntry); }
public override IProp <T> CreateWithNoValue <T> ( PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <T, T, bool> comparer, bool comparerIsRefEquality, Func <string, T> getDefaultValFunc ) { IPropTemplate <T> propTemplate = GetPropTemplate <T>(PropKindEnum.Prop, storageStrategy, comparer, comparerIsRefEquality, getDefaultValFunc); IProp <T> prop; switch (storageStrategy) { case PropStorageStrategyEnum.Internal: { // Regular Prop with Internal Storage -- Just don't have a value as yet. prop = new Prop <T>(propertyName, typeIsSolid, propTemplate); break; } case PropStorageStrategyEnum.External: { // Create a Prop that uses an external storage source. prop = new PropExternStore <T>(propertyName, extraInfo, typeIsSolid, propTemplate); break; } case PropStorageStrategyEnum.Virtual: { // This is a Prop that supplies a Virtual (aka Caclulated) value from an internal source or from LocalBindings // This implementation simply creates a Property that will always have the default value for type T. prop = new PropNoStore <T>(propertyName, typeIsSolid, propTemplate); break; } default: { throw new InvalidOperationException($"{storageStrategy} is not supported or is not recognized."); } } return(prop); }
public override ICProp <CT, T> CreateWithNoValue <CT, T> ( PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <CT, CT, bool> comparer ) { // TODO: Get a real value for comparerIsReqEquality bool comparerIsRefEquality = false; IPropTemplate <CT> propTemplate = GetPropTemplate <CT>(PropKindEnum.ObservableCollection, storageStrategy, comparer, comparerIsRefEquality, getDefaultVal: null); ICProp <CT, T> prop = new CProp <CT, T>(propertyName, typeIsSolid, propTemplate); return(prop); }
public PropTemplateTyped(PropKindEnum propKind, PropStorageStrategyEnum storageStrategy, Type propFactoryType, bool comparerIsDefault, bool comparerIsRefEquality, Func <T, T, bool> comparer, Func <string, T> defaultValFunc, bool defaultValFuncIsDefault) { PropKind = propKind; Type = typeof(T); StorageStrategy = storageStrategy; Attributes = new Attribute[] { }; ComparerIsDefault = comparerIsDefault; ComparerIsRefEquality = comparerIsRefEquality; Comparer = comparer; GetDefaultVal = defaultValFunc; PropFactoryType = propFactoryType; _hashCode = ComputetHashCode(); }
public PropDefRaw(PropCreateMethodEnum ct, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, bool useRefEquality, string type, string name, string doWhenChanged, bool doAfterNotify, string comparer, string extraInfo, string initialValue = null) { CreateType = ct; StorageStrategy = storageStrategy; TypeIsSolid = typeIsSolid; UseRefEquality = useRefEquality; PropType = type; PropName = name; DoWhenChanged = DoWhenChanged; DoAfterNotify = doAfterNotify; Comparer = comparer; ExtraInfo = extraInfo; InitialValue = initialValue; }
//// CollectionViewSource //private static IProp CreateCVSProp(IPropFactory propFactory, PropNameType propertyName, IProvideAView viewProvider, IPropTemplate propTemplate) //{ // return propFactory.CreateCVSProp(propertyName, viewProvider, propTemplate); //} //// CollectionView //private static IProp CreateCVProp(IPropFactory propFactory, PropNameType propertyName, IProvideAView viewProvider, IPropTemplate propTemplate) //{ // return propFactory.CreateCVProp(propertyName, viewProvider, propTemplate); //} #endregion #region DataSource creators //// TODO: replace IPropBagMapperGen with a IMapperRequest. //// So that the Mapper gets created only if it's needed. //private static IProvideADataSourceProvider CreateMappedDSPProvider<TSource, TDestination> // ( // IPropFactory propFactory, // PropIdType propId, // PropKindEnum propKind, // object genDal, // presumably, the value of the propItem. // PSAccessServiceInterface propStoreAccessService, // IPropBagMapperGen genMapper //, out CrudWithMapping<TSource, TDestination> mappedDs // ) where TSource : class where TDestination : INotifyItemEndEdit //{ // // Cast the genDal object back to it's original type. // IDoCRUD<TSource> dal = (IDoCRUD<TSource>)genDal; // // Cast the genMapper to it's typed-counterpart (All genMappers also implement IPropBagMapper<TS, TD> // IPropBagMapper<TSource, TDestination> mapper = (IPropBagMapper<TSource, TDestination>)genMapper; // // Now that we have performed the type casts, we can call the propFactory using "compile-time" type parameters. // ClrMappedDSP<TDestination> mappedDSP = propFactory.CreateMappedDS<TSource, TDestination>(propId, propKind, dal, propStoreAccessService, mapper); // //IProvideADataSourceProvider result = mappedDSP; // return mappedDSP; // result; //} //private static ClrMappedDSP<TDestination> CreateMappedDS_Typed<TSource, TDestination> // ( // IPropFactory propFactory, // PropIdType propId, // PropKindEnum propKind, // IDoCRUD<TSource> dal, // PSAccessServiceInterface propStoreAccessService, // IPropBagMapper<TSource, TDestination> mapper //, out CrudWithMapping<TSource, TDestination> mappedDs // ) where TSource : class where TDestination : INotifyItemEndEdit //{ // ClrMappedDSP<TDestination> result = propFactory.CreateMappedDS<TSource, TDestination>(propId, propKind, dal, propStoreAccessService, mapper); // //mappedDs = null; // return result; //} #endregion #region Scalar Prop Creation // From Object private static IProp <T> CreateProp <T> ( IPropFactory propFactory, bool haveValue, object value, bool useDefault, PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool isTypeSolid, Delegate comparer, bool useRefEquality, Delegate getDefaultValFunc ) { Func <T, T, bool> comparerToUse = GetComparerForProps <T>(comparer, propFactory, useRefEquality); // If the caller did not provide a function used to get the default value, use the default-value-getter provided by the factory. Func <string, T> getDefaultValFuncToUse = (Func <string, T>)getDefaultValFunc ?? propFactory.ValueConverter.GetDefaultValue <T>; if (haveValue || useDefault) { T initialValue; if (useDefault) { initialValue = getDefaultValFuncToUse(propertyName); } else { // TODO: the caller must provide this function the prop factory is not responsible for this. // The InitialValueField from the PropModel has a Func<object> property that the caller can use. initialValue = propFactory.GetValueFromObject <T>(value); } return(propFactory.Create(initialValue, propertyName, extraInfo, storageStrategy, isTypeSolid, comparerToUse, useRefEquality, getDefaultValFuncToUse)); } else { return(propFactory.CreateWithNoValue <T>(propertyName, extraInfo, storageStrategy, isTypeSolid, comparerToUse, useRefEquality, getDefaultValFuncToUse)); } }
// Type, Name, StorageStrategy, Kinde and Initial Value -- With ItemType public PropItemModel(Type type, string name, PropStorageStrategyEnum storageStrategy, PropKindEnum propKind, IPropInitialValueField initialValueField, Type itemType) : this ( type : type, name : name, storageStrategy : storageStrategy, typeIsSolid : true, propKind : propKind, propTypeInfoField : null, initialValueField : initialValueField, extraInfo : null, comparer : null, itemType : itemType, binderField : null, mapperRequest : null, propCreator : null ) { }
public override IProp <T> Create <T> ( T initialValue, PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <T, T, bool> comparer, bool comparerIsRefEquality, Func <string, T> getDefaultValFunc ) { IPropTemplate <T> propTemplate = GetPropTemplate <T>(PropKindEnum.Prop, storageStrategy, comparer, comparerIsRefEquality, getDefaultValFunc); propTemplate.PropCreator = CookedScalarPropCreator <T>; IProp <T> prop = new Prop <T>(propertyName, initialValue, typeIsSolid, propTemplate); return(prop); }
//Lazy<IValueConverter> _defaultConverter; //public virtual Lazy<IValueConverter> DefaultConverter //{ // get // { // if(_defaultConverter == null) // { // return new Lazy<IValueConverter>(() => new PropValueConverter()); // } // return _defaultConverter; // } // set // { // _defaultConverter = value; // } //} //Func<BindingTarget, MyBindingInfo, Type, string, object> _defConvParamBuilder; //public virtual Func<BindingTarget, MyBindingInfo, Type, string, object> DefaultConverterParameterBuilder //{ // get // { // if (_defConvParamBuilder == null) // { // return OurDefaultConverterParameterBuilder; // } // return _defConvParamBuilder; // } // set // { // _defConvParamBuilder = value; // } //} #endregion #region Constructor public LocalBinder(PSAccessServiceInterface propStoreAccessService, ExKeyT bindingTarget, LocalBindingInfo bindingInfo) { _bindingTarget = bindingTarget; _bindingInfo = bindingInfo; // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. BagNode ourNode = GetPropBagNode(propStoreAccessService); // Get a weak reference to the PropBag hosting the target property. _targetObject = ourNode.PropBagProxy; // Get the name of the target property from the PropId given to us. if (_targetObject.TryGetTarget(out IPropBag propBag)) { PropIdType propId = _bindingTarget.Level2Key; _propertyName = GetPropertyName(propStoreAccessService, propBag, propId, out PropStorageStrategyEnum storageStrategy); if (storageStrategy == PropStorageStrategyEnum.External) { throw new InvalidOperationException($"{storageStrategy} is not a supported Prop Storage Strategy when used as a target of a local binding."); } // We will update the target property depending on how that PropItem stores its value. _targetStorageStrategy = storageStrategy; // Create a instance of our nested, internal class that reponds to Updates to the property store Nodes. IReceivePropStoreNodeUpdates_PropNode <T> propStoreNodeUpdateReceiver = new PropStoreNodeUpdateReceiver(this); // Create a new watcher, the bindingInfo specifies the PropItem for which to listen to changes, // the propStoreNodeUpdateReceiver will be notfied when changes occur. _localWatcher = new LocalWatcher <T>(propStoreAccessService, bindingInfo, propStoreNodeUpdateReceiver); } else { // TODO: consider creating a TryCreateLocalBinding to avoid this situation. System.Diagnostics.Debug.WriteLine("The target was found to have been Garbage Collected when creating a Local Binding."); } }
public override IProp <T> CreateWithNoValue <T> ( PropNameType propertyName, object extraInfo, PropStorageStrategyEnum storageStrategy, bool typeIsSolid, Func <T, T, bool> comparer, bool comparerIsRefEquality, Func <string, T> getDefaultValFunc ) { IPropTemplate <T> propTemplate = GetPropTemplate <T>(PropKindEnum.Prop, storageStrategy, comparer, comparerIsRefEquality, getDefaultValFunc); if (storageStrategy == PropStorageStrategyEnum.Internal) { propTemplate.PropCreator = CookedScalarPropCreatorNoVal <T>; } else { propTemplate.PropCreator = CookedScalarPropCreatorNoStore <T>; } if (storageStrategy == PropStorageStrategyEnum.Internal) { // Regular Prop with Internal Storage -- Just don't have a value as yet. IProp <T> prop = new Prop <T>(propertyName, typeIsSolid, propTemplate); return(prop); } else { // Prop With External Store, or this is a Prop that supplies a Virtual (aka Caclulated) value from an internal source or from LocalBindings // This implementation simply creates a Property that will always have the default value for type T. IProp <T> prop = new PropNoStore <T>(propertyName, typeIsSolid, propTemplate); return(prop); } }
public LocalBinder(PSAccessServiceInterface propStoreAccessService, ExKeyT ownerPropId, LocalBindingInfo bindingInfo) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInterface>(propStoreAccessService); _bindingTarget = ownerPropId; _bindingInfo = bindingInfo; _storeNodeUpdateReceiver = null; // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. _ourNode = GetPropBagNode(propStoreAccessService); PropIdType propId = _bindingTarget.Level2Key; _targetObject = _ourNode.PropBagProxy; if (_targetObject.TryGetTarget(out IPropBagInternal propBag)) { _propertyName = GetPropertyName(propStoreAccessService, propBag, propId, out PropStorageStrategyEnum storageStrategy); _targetHasStore = storageStrategy; } _pathElements = GetPathElements(_bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } _pathListeners = new OSCollection <T>(); _isComplete = StartBinding(_targetObject, _pathElements, _pathListeners, _isPathAbsolute); }
private IPropItemModel ProcessProp(IPropTemplateItem pi, DoWhenChangedHelper doWhenChangedHelper) { PropStorageStrategyEnum storageStrategy = pi.StorageStrategy; bool typeIsSolid = pi.TypeIsSolid; string extraInfo = pi.ExtraInfo; IPropItemModel rpi = new PropItemModel ( type: pi.PropertyType, name: pi.PropertyName, storageStrategy: storageStrategy, typeIsSolid: typeIsSolid, propKind: pi.PropKind, propTypeInfoField: null, initialValueField: null, extraInfo: extraInfo, comparer: null, itemType: null, binderField: null, mapperRequest: null, propCreator: null ); bool isCProp = pi.PropKind.IsCollection(); bool foundTypeInfoField = false; ItemCollection items = ((PropItem)pi).Items; foreach (Control uc in items) { // ToDo: Find and process this field first, and then enter the enclosing foreach loop. // because one day, some of the other processing may depend on the PropertyType. // Type Info Field if (uc is DRM.PropBagControlsWPF.TypeInfoField tif) { foundTypeInfoField = true; Type propertyType = GetTypeFromInfoField(tif, pi.PropKind, pi.PropertyType, out Type itemType); if (isCProp) { rpi.CollectionType = propertyType; rpi.ItemType = itemType; } else { rpi.PropertyType = propertyType; rpi.ItemType = null; } } // Initial Value Field else if (uc is InitialValueField ivf) { IPropInitialValueField rivf; // TODO: Add error handling here. if (ivf.PropBagFullClassName != null) { rivf = PropInitialValueField.FromPropBagFCN(ivf.PropBagFullClassName); } else if (ivf.CreateNew) { rivf = PropInitialValueField.UseCreateNew; } else { rivf = new PropInitialValueField(ivf.InitialValue, ivf.SetToDefault, ivf.SetToUndefined, ivf.SetToNull, ivf.SetToEmptyString); } rpi.InitialValueField = rivf; } // Do When Changed Field else if (uc is DRM.PropBagControlsWPF.PropDoWhenChangedField dwc) { MethodInfo mi = doWhenChangedHelper.GetMethodAndSubKind(dwc, rpi.PropertyType, rpi.PropertyName, out SubscriptionKind subscriptionKind); SubscriptionPriorityGroup priorityGroup = dwc?.DoAfterNotify ?? false ? SubscriptionPriorityGroup.Last : SubscriptionPriorityGroup.Standard; IPropDoWhenChangedField rdwc = new DRM.PropBag.PropDoWhenChangedField ( target: null, method: mi, subscriptionKind: subscriptionKind, priorityGroup: priorityGroup, methodIsLocal: true, declaringType: null, fullClassName: null, instanceKey: null ); rpi.DoWhenChangedField = rdwc; } // Comparer Field else if (uc is DRM.PropBagControlsWPF.PropComparerField pcf) { IPropComparerField rpcf = new PropBag.PropComparerField(pcf.ComparerFunc.Comparer, pcf.UseRefEquality); rpi.ComparerField = rpcf; } // Local Binder Field else if (uc is DRM.PropBagControlsWPF.PropBinderField binderField) { IPropBinderField rBinderField = new PropBag.PropBinderField(binderField.Path); rpi.BinderField = rBinderField; rpi.MapperRequestResourceKey = binderField.MapperRequestResourceKey; } } if (!foundTypeInfoField) { if (isCProp) { Type propertyType = GetTypeFromInfoField(null, pi.PropKind, pi.PropertyType, out Type itemType); rpi.CollectionType = propertyType; rpi.ItemType = itemType; } else if (pi.PropKind == PropKindEnum.CollectionView) { rpi.PropertyType = typeof(ListCollectionView); rpi.CollectionType = rpi.PropertyType; rpi.ItemType = pi.PropertyType; } else { // TODO: Check other PropKinds. // Do Nothing. } } return(rpi); }
// TODO: should be able to have IPropStoreAccessServiceInternal provide all of this with a single call. private PropNameType GetPropertyName(PSAccessServiceInterface propStoreAccessService, IPropBag propBag, PropIdType propId, out PropStorageStrategyEnum storageStrategy) { PropNameType result; if (propStoreAccessService.TryGetPropName(propId, out PropNameType propertyName)) { result = propertyName; } else { throw new InvalidOperationException("Cannot retrieve the Target's property name from the TargetPropId."); } if (propStoreAccessService.TryGetValue(propBag, propId, out IPropData genProp)) { storageStrategy = genProp.TypedProp.PropTemplate.StorageStrategy; } else { throw new InvalidOperationException("Cannot retrieve the Target's property name from the TargetPropId."); } return(result); }
public abstract ICProp <CT, T> Create <CT, T>( CT initialValue, PropNameType propertyName, object extraInfo = null, PropStorageStrategyEnum storageStrategy = PropStorageStrategyEnum.Internal, bool typeIsSolid = true, Func <CT, CT, bool> comparer = null) where CT : class, IReadOnlyList <T>, IList <T>, IEnumerable <T>, IList, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged;