#region Imports using System; using System.Collections.Generic; using System.Linq; using System.ComponentModel; using System.Collections.ObjectModel; #endregion public sealed class DictionaryObject : KeyedCollection>, ICustomTypeDescriptor { PropertyDescriptorCollection _cachedProperties; public DictionaryObject() : this(null, null) { } public DictionaryObject(IEqualityComparer comparer) : this(null, comparer) { } public DictionaryObject(IEnumerable> dict) : this(dict, null) {} public DictionaryObject(IEnumerable> dict, IEqualityComparer comparer) : base(comparer ?? StringComparer.OrdinalIgnoreCase) { if (dict != null) { foreach (var pair in dict) Add(pair); } } public new T this[int index] { get { return base[index].Value; } set { var e = base[index]; base[index] = new KeyValuePair(e.Key, value); } } public new T this[string key] { get { return base[key].Value; } set { Remove(key); Add(key, value); } } public void Add(string key, T value) { Add(new KeyValuePair(key, value)); } protected override string GetKeyForItem(KeyValuePair item) { return item.Key; } protected override void ClearItems() { ClearCachedProperties(); base.ClearItems(); } protected override void InsertItem(int index, KeyValuePair item) { ClearCachedProperties(); base.InsertItem(index, item); } protected override void RemoveItem(int index) { ClearCachedProperties(); base.RemoveItem(index); } protected override void SetItem(int index, KeyValuePair item) { ClearCachedProperties(); base.SetItem(index, item); } private void ClearCachedProperties() { _cachedProperties = null; } AttributeCollection ICustomTypeDescriptor.GetAttributes() { return new AttributeCollection(null); } string ICustomTypeDescriptor.GetClassName() { return null; } string ICustomTypeDescriptor.GetComponentName() { return null; } TypeConverter ICustomTypeDescriptor.GetConverter() { return null; } EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return null; } PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return null; } object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return null; } EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return GetEvents(); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return GetEvents(); } object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return null; } private static EventDescriptorCollection GetEvents() { return new EventDescriptorCollection(null); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { if (attributes != null && attributes.Length > 0) throw new NotSupportedException(); return GetProperties(); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return GetProperties(); } private PropertyDescriptorCollection GetProperties() { if (_cachedProperties == null) { _cachedProperties = new PropertyDescriptorCollection( this.Select(e => new DictionaryPropertyDescriptor(e.Key)).ToArray()); } return _cachedProperties; } private sealed class DictionaryPropertyDescriptor : PropertyDescriptor { public DictionaryPropertyDescriptor(string name) : base(name, null) { } public override bool CanResetValue(object component) { return false; } public override Type ComponentType { get { throw new NotImplementedException(); } } public override object GetValue(object component) { return ((DictionaryObject) component)[Name]; } public override bool IsReadOnly { get { return false; } } public override Type PropertyType { get { return typeof(T); } } public override void ResetValue(object component) { throw new NotSupportedException(); } public override void SetValue(object component, object value) { ((DictionaryObject) component)[Name] = (T) value; } public override bool ShouldSerializeValue(object component) { throw new NotSupportedException(); } } }