public void DynamicFill(IEnumerable <IFormTreeNode> nodes, IPropertyValueConverter converter) { var objectPopulator = new ObjectPopulator(converter); foreach (var node in nodes) { var propValue = (TKey)converter.ConvertToPropertyType(typeof(TKey), node.Key); TElement element; if (elements == null || !HasKey(propValue)) { element = Activator.CreateInstance <TElement>(); Add(element); var fieldName = MemberHelpers.GetKeyPropertyFieldName <TElement>(); var(field, typeOfField) = MemberHelpers.GetPropertyField(element, fieldName); // Convert property to field, for support readonly model object fieldValue = converter.ConvertToFieldType(typeOfField, propValue); element.SetValue(field, fieldValue); } else { element = this[propValue]; } if (node is FormTreeCollection formTreeCollection) { objectPopulator.Populate(formTreeCollection.Childs, element); } else { throw new NotSupportedException(); } } }
/// <summary> /// Dynamic fill model /// </summary> /// <typeparam name="T">Type of filling object.</typeparam> /// <param name="nodes">Items of FormCollection that are prepared for this model.</param> /// <param name="obj">Object for set values from items</param> private void DynamicFill <T>(IEnumerable <IFormTreeNode> nodes, T obj) { if (obj is IDynamicFillModel dynamicFillModel) { dynamicFillModel.DynamicFill(nodes, Converter); return; } if (!(obj is IDynamicFillModeController dynamicFillModeController)) { dynamicFillModeController = null; } dynamicFillModeController?.OnStartFillModel(nodes); foreach (var node in nodes) { // Simple property if (node is FormTreeNode fte) { // Search fields var(member, declaringType) = MemberHelpers.GetPropertyField(obj, fte.Key); // If FormCollection have other system fields if (member == null) { continue; } dynamicFillModeController?.OnBeforeSetPropertyValue(node, fte.Key, fte.Value); AutoSetValueMember(obj, fte.Key, member, declaringType, fte.Value, Converter); } // Properties collection else if (node is FormTreeCollection ftc) { // Search fields var(member, declaringType) = MemberHelpers.GetPropertyField(obj, node.Key); // If FormCollection have other system fields if (member == null) { continue; } object includedModel = null; if (member is FieldInfo field) { includedModel = field.GetValue(obj); if (includedModel == null) { includedModel = Activator.CreateInstance(field.FieldType); } dynamicFillModeController?.OnBeforeSetPropertyValue(node, node.Key, includedModel); field.SetValue(obj, includedModel); } else if (member is PropertyInfo property) { includedModel = property.GetValue(obj); if (includedModel == null) { includedModel = Activator.CreateInstance(property.PropertyType); } dynamicFillModeController?.OnBeforeSetPropertyValue(node, node.Key, includedModel); property.SetValue(obj, includedModel); } else { throw new NotImplementedException(); } if (includedModel is IDynamicFillModel dynamicCollection) { dynamicCollection.DynamicFill(ftc.Childs, Converter); } else { DynamicFill(ftc.Childs, includedModel); } //TODO: No implement Array, List, and other IEnumerable class } } dynamicFillModeController?.OnFinishFillModel(nodes.Select(x => x.Key).ToArray()); }