Мне нужно правильно отобразить объект в сетке свойств. мой класс выглядит так:

public class PropertyItem
{
    public PropertyDescription PropertyDescription { get; set; }

    [Description("the value"), Browsable(true)]
    public object Value { get; set; }

    public PropertyItem(PropertyDescription propertyDescription, object value)
    {
        PropertyDescription = propertyDescription;
        Value = value;
    }

    public override string ToString()
    {
        return this.PropertyDescription.Name + ": " + PropertyDescription.Type + ": " + Value;
    }
}

Value относится к типу object, и это нельзя изменить. PropertyDescription имеет тип Value, и это может быть что угодно (string, int, bool ...)

Когда я устанавливаю SelectedObject своего PropertyGrid, Value всегда отключается.

Как мне написать TypeConverter для преобразования object Value в Type в PropertyDescription?

2
lebhero 19 Июн 2017 в 17:33
 – 
Massimiliano Kraus
19 Июн 2017 в 17:40
Убедитесь, что это может вам помочь
 – 
Massimiliano Kraus
19 Июн 2017 в 17:45
Отображение - не главное зависание. Но кто-то каким-то образом должен будет указать тип значения, когда оно будет введено. Что такое «0»? Это просто неправильный путь.
 – 
Hans Passant
19 Июн 2017 в 18:22
Привет, Ганс, я предполагаю, что мой список будет включать правильные значения и правильные типы .. это правда, что вы говорите, но я не рассматриваю это в данный момент .. спасибо за подсказку
 – 
lebhero
19 Июн 2017 в 18:24

1 ответ

Лучший ответ

Определите преобразователь настраиваемого типа для свойства:

[TypeConverter(typeof(PropertyValueConverter))]
public object Value { get; set; }

И реализуем это так:

public class PropertyValueConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        var propItem = context.Instance as PropertyItem;
        return propItem != null && TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).CanConvertFrom(context, sourceType)
            || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).ConvertFrom(context, culture, value);
        else
            return base.ConvertFrom(context, culture, value);
    }
}

Этот тестовый код сработал для меня:

var pi = new PropertyItem(new PropertyDescription { Type = typeof(int) }, 1);
propertyGrid1.SelectedObject = pi;

Обновление:

Для поддержки раскрывающегося списка (например, bool):

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetStandardValues(context);
        else
            return base.GetStandardValues(context);
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetStandardValuesSupported(context);
        else
            return base.GetStandardValuesSupported(context);
    }

Для поддержки настраиваемых открываемых свойств (например, Point):

    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetProperties(context, value, attributes);
        else
            return base.GetProperties(context, value, attributes);
    }

    public override bool GetPropertiesSupported(ITypeDescriptorContext context)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetPropertiesSupported(context);
        return base.GetPropertiesSupported(context);
    }
4
György Kőszeg 19 Июн 2017 в 18:37
Если я проверю значение типа bool, в сетке свойств будет отображаться значение, но не в раскрывающемся списке только с True или False, но это будет пустое текстовое поле.
 – 
lebhero
19 Июн 2017 в 18:18
pi = new PropertyItem(new PropertyDescription { Type = typeof(bool) }, true); у меня работает: он не отображает пустое текстовое поле, и я могу редактировать значение. Чтобы предоставить раскрывающийся список констант bool, аналогичным образом переопределите GetProperties.
 – 
György Kőszeg
19 Июн 2017 в 18:24
Не могли бы вы отредактировать свой ответ выше, чтобы включить переопределение GetProperties, как вы сказали?
 – 
lebhero
19 Июн 2017 в 18:33
Спасибо ... я протестировал его с помощью точки, и он работает ... by bool у меня все еще есть некоторые проблемы, он не отображает раскрывающийся список, но я проверю его и дам вам знать ... еще раз спасибо
 – 
lebhero
19 Июн 2017 в 18:42