Наконец я решил эту проблему для большинства случаев:
Проблема возникает из-за того, что PropertyDescriptor
возвращает в свойстве Converter
обычно правильный преобразователь или, по крайней мере, базовый класс TypeConverter
, который по крайней мере вызовет ToString()
для визуализации. В случае свойства, которое определено как интерфейс, сетка свойств получит ReferenceConverter
, но, посмотрев в раздел замечаний
ReferenceConverter обычно используется в контексте выбранных компонентов или среды разработки. Без компонента сайта или пригодного для использования ITypeDescriptorContext этот конвертер малопригоден.
Кажется, нам это мало пригодится. К счастью, я уже использую свой собственный PropertyDescriptor
, поэтому все, что мне нужно было сделать, это переопределить свойство Converter моего дескриптора и перейти к следующему:
public override TypeConverter Converter
{
get
{
var converter = base.Converter;
// If the property of the class is a interface, the default implementation
// of PropertyDescriptor will return a ReferenceConverter, but that doesn't
// work as expected (normally the right site will stay empty).
// Instead we'll return a TypeConverter, that works on the concrete type
// and returns at least the ToString() result of the given type.
if (_OriginalPropertyDescriptor.PropertyType.IsInterface)
{
if (converter.GetType() == typeof(ReferenceConverter))
{
converter = _InterfaceConverter;
}
}
return converter;
}
}
Необходима явная проверка для ReferenceConverter
, поскольку возможно, что пользователь определил свой собственный TypeEditor через атрибут свойства, который будет автоматически соблюдаться базовой реализацией. Это может привести к проблемам, если кто-то явно скажет через атрибут, что ему нравится ReferenceConverter, но я не думаю, что этот случай должен быть обработан (но может быть, путем проверки атрибутов PropertyDescriptor).