// Copyright (c) 2019 schick Informatik // Description: Hilfsklasse zur Darstellung von untergeordneten Listen // im XCeed PropertyGrid // Idee von der 2. Antwort hier: // https://stackoverflow.com/questions/36286530/xceed-wpf-propertygrid-show-item-for-expanded-collection using System; using System.Collections.Generic; using System.Linq; using System.ComponentModel; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; using System.Collections; namespace ENI2.Util { #region class ENIExpandableIListConverter public class ENIExpandableIListConverter : ExpandableObjectConverter { public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { if (value is IList) { IList list = value as IList; PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null); IEnumerator enumerator = list.GetEnumerator(); int counter = -1; while (enumerator.MoveNext()) { counter++; propDescriptions.Add(new ListItemPropertyDescriptor(list, counter)); } return propDescriptions; } else { return base.GetProperties(context, value, attributes); } } } #endregion #region class ListItemPropertyDescriptor public class ListItemPropertyDescriptor : PropertyDescriptor { private readonly IList _owner; private readonly int index; public ListItemPropertyDescriptor(IList owner, int index) : base("[" + index + "]", null) { this._owner = owner; this.index = index; } public override AttributeCollection Attributes { get { var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); //If the Xceed expandable object attribute is not applied then apply it if (!attributes.OfType().Any()) { attributes = AddAttribute(new ExpandableObjectAttribute(), attributes); } //set the xceed order attribute return AddAttribute(new PropertyOrderAttribute(index), attributes); } } private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) { Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1]; oldAttributes.CopyTo(newAttributes, 1); newAttributes[0] = newAttribute; return new AttributeCollection(newAttributes); } public override bool CanResetValue(object component) { return false; } public override object GetValue(object component) { return Value; } private T Value => _owner[index]; public override void ResetValue(object component) { throw new NotImplementedException(); } public override void SetValue(object component, object value) { _owner[index] = (T)value; } public override bool ShouldSerializeValue(object component) { return false; } public override Type ComponentType => _owner.GetType(); public override bool IsReadOnly => false; public override Type PropertyType => Value?.GetType(); } #endregion #region class TypeDecorationManager public static class TypeDecorationManager { public static void AddExpandableObjectConverter(Type T) { TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(ExpandableObjectConverter))); TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute()); } public static void AddExpandableIListConverter(Type T) { TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(ENIExpandableIListConverter))); TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute()); } } #endregion }