зеркало из https://github.com/DeGsoft/maui-linux.git
178 строки
4.8 KiB
C#
178 строки
4.8 KiB
C#
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<string, object>
|
|
{
|
|
readonly Dictionary<string, object> _innerDictionary = new Dictionary<string, object>();
|
|
|
|
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<Type, ResourceDictionary> _instances;
|
|
static ResourceDictionary GetInstance(Type type)
|
|
{
|
|
_instances = _instances ?? new Dictionary<Type, ResourceDictionary>();
|
|
ResourceDictionary rd;
|
|
if (!_instances.TryGetValue(type, out rd))
|
|
{
|
|
rd = ((ResourceDictionary)Activator.CreateInstance(type));
|
|
_instances [type] = rd;
|
|
}
|
|
return rd;
|
|
}
|
|
|
|
ResourceDictionary _mergedInstance;
|
|
|
|
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
|
|
{
|
|
((ICollection<KeyValuePair<string, object>>)_innerDictionary).Add(item);
|
|
OnValuesChanged(item);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_innerDictionary.Clear();
|
|
}
|
|
|
|
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
|
|
{
|
|
return ((ICollection<KeyValuePair<string, object>>)_innerDictionary).Contains(item);
|
|
}
|
|
|
|
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
|
{
|
|
((ICollection<KeyValuePair<string, object>>)_innerDictionary).CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { return _innerDictionary.Count + (_mergedInstance != null ? _mergedInstance.Count: 0); }
|
|
}
|
|
|
|
bool ICollection<KeyValuePair<string, object>>.IsReadOnly
|
|
{
|
|
get { return ((ICollection<KeyValuePair<string, object>>)_innerDictionary).IsReadOnly; }
|
|
}
|
|
|
|
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
|
|
{
|
|
return ((ICollection<KeyValuePair<string, object>>)_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($"The resource '{index}' is not present in the dictionary.");
|
|
}
|
|
set
|
|
{
|
|
_innerDictionary[index] = value;
|
|
OnValueChanged(index, value);
|
|
}
|
|
}
|
|
|
|
public ICollection<string> Keys
|
|
{
|
|
get { return _innerDictionary.Keys; }
|
|
}
|
|
|
|
public bool Remove(string key)
|
|
{
|
|
return _innerDictionary.Remove(key);
|
|
}
|
|
|
|
public ICollection<object> Values
|
|
{
|
|
get { return _innerDictionary.Values; }
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
|
{
|
|
var rd = (IEnumerable<KeyValuePair<string,object>>)_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<ResourcesChangedEventArgs> 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<Style> classes;
|
|
object outclasses;
|
|
if (!TryGetValue(Style.StyleClassPrefix + style.Class, out outclasses) || (classes = outclasses as IList<Style>) == null)
|
|
classes = new List<Style>();
|
|
classes.Add(style);
|
|
this[Style.StyleClassPrefix + style.Class] = classes;
|
|
}
|
|
}
|
|
|
|
void OnValueChanged(string key, object value)
|
|
{
|
|
OnValuesChanged(new KeyValuePair<string, object>(key, value));
|
|
}
|
|
|
|
void OnValuesChanged(params KeyValuePair<string, object>[] values)
|
|
{
|
|
if (values == null || values.Length == 0)
|
|
return;
|
|
ValuesChanged?.Invoke(this, new ResourcesChangedEventArgs(values));
|
|
}
|
|
|
|
event EventHandler<ResourcesChangedEventArgs> ValuesChanged;
|
|
}
|
|
} |