Как добавить свойства combiox Dynami c в таблицу свойств, используя пользовательское свойство? - PullRequest
0 голосов
/ 05 марта 2020

Мне нужно создать некоторые динамические c свойства в сетке свойств, основанные на каком-либо действии. Я могу создать динамические свойства c, следуя примеру https://www.codeproject.com/Articles/9280/Add-Remove-Items-to-from-PropertyGrid-at-Runtime. Но мне также нужно добавить комбинированный список в сетку свойств. Для этого я создал класс, производный от stringConverter. Как показано ниже:

 public class FormatStringConverter : StringConverter
{
    public override Boolean GetStandardValuesSupported(ITypeDescriptorContext context) { return true; }
    public override Boolean GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; }
    public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        List<String> list = new List<String>();
        list.Add("DepartmentA");        
        list.Add("DepartmentB");                
        list.Add("DepartmentC");
        return new StandardValuesCollection(list);
    }
}

Но в примере customClass, что я должен вернуть, чтобы показать значения stringConverters в виде поля со списком в таблице свойств?

TypeConverter GetConverter()
{
   if(prop.Name == "department")
       //what to return here?
   else
       return TypeDescriptor.GetConverter(this, true);
}

Если кто-нибудь решит это с помощью других TypeConverters, я оценю, если это помогает моему делу.

1 Ответ

0 голосов
/ 09 марта 2020

Вы можете обратиться к примеру Мар c Гравелла здесь. Динамика привязки данных c данные Мне пришлось настроить чужой код, чтобы раскрывающиеся списки работали, и я прошу прощения, если это не полный список.

  1. Ваш пользовательский Метод класса GetConverter () должен просто возвращать TypeDescriptor.GetConverter (this, true).

  2. Если вы не знаете, свойства динамического c вашего пользовательского класса не будут работать с DataGridView, из-за того, как DGV читает их. Так что моя реализация здесь ограничена PropertyGrid. Попытка использовать DataGridView вместе с ICustomTypeDescriptor

  3. Решить, должен ли выпадающий список PropertyGrid быть редактируемым. Как добавить редактируемый комбинированный список в Систему. Windows .Forms.PropertyGrid?

    // also necessary to make propertyInfo work
    // this allows us to assign lists to propertyGrid dropdowns
    [TypeConverter(typeof(PrebuiltListConverter))]
    public class DecoratedDropdown { }

    public class PrebuiltListConverter : StringConverter
    {
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            CvarPropertyDescriptor descriptor = (CvarPropertyDescriptor)context.PropertyDescriptor;
            return new StandardValuesCollection(descriptor.Options);
        }

        public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; }
        // credit Zlatko; return false in StringConverter subclass to make editable combobox
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return false; }
    }
Ваш пользовательский PropertyDescriptor должен сохранять ссылку на ваше пользовательское свойство (например, m_Property ниже). Он также должен переопределить PropertyType, чтобы возвращать тип, связанный с A) типом пользовательского класса, когда нет раскрывающегося списка, или B) вашим подклассом, декорированным выпадающим списком StringConverter.
    public override Type PropertyType { get { return m_Property.Type; } }

Я использую тип свойство в моем классе пользовательского свойства, чтобы принять это решение:

PropertyDescriptor требуется динамический c, чтобы получить список необязательных значений для этого свойства, список, который я храню в своем классе пользовательских свойств. Я не могу сказать, работает ли представление необязательных значений с помощью List.
    public ICollection Options { get { dynamic dObj = m_Property; return dObj.PossibleValues; } }
Ваш пользовательский класс должен иметь полную реализацию TypeDescriptor.
public String GetClassName() { return TypeDescriptor.GetClassName(this, true); }
        public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); }
        public String GetComponentName() { return TypeDescriptor.GetComponentName(this, true); }
        public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); }
        public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); }
        public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); }
        public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); }
        public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); }
        public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); }
        // GetProperties(Attribute[] attributes) etc.
        public PropertyDescriptorCollection GetProperties() { return TypeDescriptor.GetProperties(this, true); }
        public object GetPropertyOwner(PropertyDescriptor pd) { return this; }

Дайте мне знать, если я что-то пропустил. Я сделал это довольно недавно.

...