146 lines
4.4 KiB
C#
146 lines
4.4 KiB
C#
// 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<T>
|
|
|
|
public class ENIExpandableIListConverter<T> : ExpandableObjectConverter
|
|
{
|
|
|
|
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
|
|
{
|
|
if (value is IList<T>)
|
|
{
|
|
IList<T> list = value as IList<T>;
|
|
PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null);
|
|
IEnumerator enumerator = list.GetEnumerator();
|
|
int counter = -1;
|
|
while (enumerator.MoveNext())
|
|
{
|
|
counter++;
|
|
propDescriptions.Add(new ListItemPropertyDescriptor<T>(list, counter));
|
|
|
|
}
|
|
return propDescriptions;
|
|
}
|
|
else
|
|
{
|
|
return base.GetProperties(context, value, attributes);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region class ListItemPropertyDescriptor
|
|
|
|
public class ListItemPropertyDescriptor<T> : PropertyDescriptor
|
|
{
|
|
private readonly IList<T> _owner;
|
|
private readonly int index;
|
|
|
|
public ListItemPropertyDescriptor(IList<T> 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<ExpandableObjectAttribute>().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<I>(Type T)
|
|
{
|
|
TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(ENIExpandableIListConverter<I>)));
|
|
TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute());
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|