1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
5
using System.Diagnostics;
6
using System.Collections;
7
using System.ComponentModel;
8
using System.Globalization;
9
using System.Reflection;
11
using System.Windows.Markup;
13
namespace ICSharpCode.WpfDesign.XamlDom
16
/// Static class containing helper methods to work with collections (like the XamlParser does)
18
public static class CollectionSupport
21
/// Gets if the type is considered a collection in XAML.
23
public static bool IsCollectionType(Type type)
25
return typeof(IList).IsAssignableFrom(type)
27
|| typeof(IAddChild).IsAssignableFrom(type)
28
|| typeof(ResourceDictionary).IsAssignableFrom(type);
32
/// Gets if the collection type <paramref name="col"/> can accepts items of type
33
/// <paramref name="item"/>.
35
public static bool CanCollectionAdd(Type col, Type item)
37
var e = col.GetInterface("IEnumerable`1");
38
if (e != null && e.IsGenericType) {
39
var a = e.GetGenericArguments()[0];
40
return a.IsAssignableFrom(item);
46
/// Gets if the collection type <paramref name="col"/> can accept the specified items.
48
public static bool CanCollectionAdd(Type col, IEnumerable items)
50
foreach (var item in items) {
51
if (!CanCollectionAdd(col, item.GetType())) return false;
57
/// Adds a value to the end of a collection.
59
public static void AddToCollection(Type collectionType, object collectionInstance, XamlPropertyValue newElement)
61
IAddChild addChild = collectionInstance as IAddChild;
62
if (addChild != null) {
63
if (newElement is XamlTextValue) {
64
addChild.AddText((string)newElement.GetValueFor(null));
66
addChild.AddChild(newElement.GetValueFor(null));
68
} else if (collectionInstance is ResourceDictionary) {
69
object val = newElement.GetValueFor(null);
70
object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("Key") : null;
73
key = ((Style)val).TargetType;
75
((ResourceDictionary)collectionInstance).Add(key, val);
77
collectionType.InvokeMember(
78
"Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance,
79
null, collectionInstance,
80
new object[] { newElement.GetValueFor(null) },
81
CultureInfo.InvariantCulture);
86
/// Adds a value at the specified index in the collection.
88
public static void Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index)
90
collectionType.InvokeMember(
91
"Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance,
92
null, collectionInstance,
93
new object[] { index, newElement.GetValueFor(null) },
94
CultureInfo.InvariantCulture);
97
static readonly Type[] RemoveAtParameters = { typeof(int) };
100
/// Removes the item at the specified index of the collection.
102
/// <returns>True if the removal succeeded, false if the collection type does not support RemoveAt.</returns>
103
public static bool RemoveItemAt(Type collectionType, object collectionInstance, int index)
105
MethodInfo m = collectionType.GetMethod("RemoveAt", RemoveAtParameters);
107
m.Invoke(collectionInstance, new object[] { index });
115
/// Removes an item instance from the specified collection.
117
public static void RemoveItem(Type collectionType, object collectionInstance, object item)
119
collectionType.InvokeMember(
120
"Remove", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance,
121
null, collectionInstance,
122
new object[] { item },
123
CultureInfo.InvariantCulture);