/// <summary> /// Adds a value to the end of a collection. /// </summary> public static void AddToCollection(Type collectionType, object collectionInstance, XamlPropertyValue newElement) { IAddChild addChild = collectionInstance as IAddChild; if (addChild != null) { if (newElement is XamlTextValue) { addChild.AddText((string)newElement.GetValueFor(null)); } else { addChild.AddChild(newElement.GetValueFor(null)); } } else if (collectionInstance is IDictionary) { object val = newElement.GetValueFor(null); object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("Key") : null; if (key == null || (key as string) == "") { if (val is Style) { key = ((Style)val).TargetType; } } if (key == null || (key as string) == "") { key = val; } ((IDictionary)collectionInstance).Add(key, val); } else { collectionType.InvokeMember( "Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { newElement.GetValueFor(null) }, CultureInfo.InvariantCulture); } }
/// <summary> /// Adds a value at the specified index in the collection. /// </summary> public static bool Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { object value = newElement.GetValueFor(null); // Using IList, with possible Add instead of Insert, was primarily added as a workaround // for a peculiarity (or bug) with collections inside System.Windows.Input namespace. // See CollectionTests.InputCollectionsPeculiarityOrBug test method for details. var list = collectionInstance as IList; if (list != null) { if (list.Count == index) { list.Add(value); } else { list.Insert(index, value); } return(true); } else { var hasInsert = collectionType.GetMethods().Any(x => x.Name == "Insert"); if (hasInsert) { collectionType.InvokeMember( "Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { index, value }, CultureInfo.InvariantCulture); return(true); } } return(false); }