using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Reflection; using System.Linq; namespace Xamarin.Forms { public class ResourceDictionary : IResourceDictionary, IDictionary { readonly Dictionary _innerDictionary = new Dictionary(); Type _mergedWith; [TypeConverter (typeof(TypeTypeConverter))] public Type MergedWith { get { return _mergedWith; } set { if (_mergedWith == value) return; _mergedWith = value; if (_mergedWith == null) return; _mergedInstance = _mergedWith.GetTypeInfo().BaseType.GetTypeInfo().DeclaredMethods.First(mi => mi.Name == "GetInstance").Invoke(null, new object[] {_mergedWith}) as ResourceDictionary; OnValuesChanged (_mergedInstance.ToArray()); } } static Dictionary _instances; static ResourceDictionary GetInstance(Type type) { _instances = _instances ?? new Dictionary(); ResourceDictionary rd; if (!_instances.TryGetValue(type, out rd)) { rd = ((ResourceDictionary)Activator.CreateInstance(type)); _instances [type] = rd; } return rd; } ResourceDictionary _mergedInstance; void ICollection>.Add(KeyValuePair item) { ((ICollection>)_innerDictionary).Add(item); OnValuesChanged(item); } public void Clear() { _innerDictionary.Clear(); } bool ICollection>.Contains(KeyValuePair item) { return ((ICollection>)_innerDictionary).Contains(item); } void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { ((ICollection>)_innerDictionary).CopyTo(array, arrayIndex); } public int Count { get { return _innerDictionary.Count + (_mergedInstance != null ? _mergedInstance.Count: 0); } } bool ICollection>.IsReadOnly { get { return ((ICollection>)_innerDictionary).IsReadOnly; } } bool ICollection>.Remove(KeyValuePair item) { return ((ICollection>)_innerDictionary).Remove(item); } public void Add(string key, object value) { _innerDictionary.Add(key, value); OnValueChanged(key, value); } public bool ContainsKey(string key) { return _innerDictionary.ContainsKey(key); } [IndexerName("Item")] public object this[string index] { get { if (_innerDictionary.ContainsKey(index)) return _innerDictionary[index]; if (_mergedInstance != null && _mergedInstance.ContainsKey(index)) return _mergedInstance[index]; throw new KeyNotFoundException(); } set { _innerDictionary[index] = value; OnValueChanged(index, value); } } public ICollection Keys { get { return _innerDictionary.Keys; } } public bool Remove(string key) { return _innerDictionary.Remove(key); } public ICollection Values { get { return _innerDictionary.Values; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator> GetEnumerator() { var rd = (IEnumerable>)_innerDictionary; if (_mergedInstance != null) rd = rd.Concat(_mergedInstance._innerDictionary); return rd.GetEnumerator(); } public bool TryGetValue(string key, out object value) { return _innerDictionary.TryGetValue(key, out value) || (_mergedInstance != null && _mergedInstance.TryGetValue(key, out value)); } event EventHandler IResourceDictionary.ValuesChanged { add { ValuesChanged += value; } remove { ValuesChanged -= value; } } public void Add(Style style) { if (string.IsNullOrEmpty(style.Class)) Add(style.TargetType.FullName, style); else { IList