/// <summary> /// Creates the or update array map. /// </summary> protected virtual void CreateOrUpdateArrayMap(object viewModel, PropertyInfo parentProperty, ref ViewModelMapNode map) { if (map == null) { map = new ViewModelMapArrayNode(); } if (map is ViewModelMapArrayNode) { var itemValues = ((IEnumerable)viewModel).OfType<object>().ToList(); var typedMap = (ViewModelMapArrayNode)map; // if the collection can be compared and updated by some property key, do it, otherwise replace the collection contents; // the synchronization can only occur when there is a key map or when the collection is empty var keyName = ResolveCollectionKeyName(parentProperty); if (!string.IsNullOrEmpty(keyName) && typedMap.Items.Count == typedMap.KeyMap.Count) { SynchronizeCollections(typedMap, itemValues, keyName); } else { // replace collection contents typedMap.Items.Clear(); typedMap.Items.AddRange(itemValues.Select(i => CreateMap(i, null))); typedMap.KeyMap.Clear(); } } else { throw new Exception(string.Format("The viewModel is a collection or array but the {0} was expected.", map.GetType())); } }
/// <summary> /// Applies the specified view model contents to the specified view model map. /// </summary> public virtual void CreateOrUpdateMap(object viewModel, PropertyInfo parentProperty, ref ViewModelMapNode map) { if (IsPrimitiveValue(viewModel)) { // view model is primitive type value CreateOrUpdateConstantMap(viewModel, ref map); } else if (IsCollectionOrArray(viewModel)) { // view model is a collection or an array CreateOrUpdateArrayMap(viewModel, parentProperty, ref map); } else { // view model is an object with properties CreateOrUpdatePropertyMap(viewModel, parentProperty, ref map); } }
/// <summary> /// Creates the or update property map. /// </summary> protected virtual void CreateOrUpdatePropertyMap(object viewModel, PropertyInfo parentProperty, ref ViewModelMapNode map) { if (map == null) { map = new ViewModelMapObjectNode(); } if (map is ViewModelMapObjectNode) { // get property values var propertyMaps = viewModel.GetType().GetProperties().Where(p => p.CanRead).Select(p => new { Property = p, Name = p.Name, Value = p.GetValue(viewModel) }).ToList(); // add or update properties in the object var typedMap = (ViewModelMapObjectNode)map; foreach (var propertyMap in propertyMaps) { if (typedMap.Properties.ContainsKey(propertyMap.Name)) { var currentValue = typedMap.Properties[propertyMap.Name]; CreateOrUpdateMap(propertyMap.Value, propertyMap.Property, ref currentValue); typedMap.Properties[propertyMap.Name] = currentValue; } else { typedMap.Properties[propertyMap.Name] = CreateMap(propertyMap.Value, propertyMap.Property); } } } else { throw new Exception(string.Format("The viewModel is an object but the {0} was expected.", map.GetType())); } }
/// <summary> /// Creates the or update constant map. /// </summary> protected virtual void CreateOrUpdateConstantMap(object viewModel, ref ViewModelMapNode map) { if (map == null) { map = new ViewModelMapPrimitiveNode() { Value = viewModel }; } else if (map is ViewModelMapPrimitiveNode) { ((ViewModelMapPrimitiveNode)map).Value = viewModel; } else { throw new Exception(string.Format("The viewModel is primitive value but but {0} was expected.", map.GetType())); } }