【问题标题】:How to add dynamic combobox properties in propertygrid using custom property?如何使用自定义属性在 propertygrid 中添加动态组合框属性?
【发布时间】:2020-03-04 22:05:32
【问题描述】:

我必须根据某些操作在 propertygrid 中创建一些动态属性。我可以按照https://www.codeproject.com/Articles/9280/Add-Remove-Items-to-from-PropertyGrid-at-Runtime 示例创建动态属性。但我还需要在 propertygrid 中添加一个组合框。为此,我创建了一个从 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 中,我应该返回什么以在 propertygrid 中将 stringConverters 值显示为组合框?

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

如果有人使用其他 TypeConverters 解决了它,我会感谢它是否有助于我的事业。

【问题讨论】:

    标签: c# winforms wpf-controls propertygrid


    【解决方案1】:

    您可以在此处参考 Marc Gravell 的示例。 Data binding dynamic data 我不得不调整其他人的代码以使下拉菜单正常工作,如果这不是一个完整的列表,我深表歉意。

    1. 您的自定义类的 GetConverter() 方法应该只返回 TypeDescriptor.GetConverter(this, true)。

    2. 如果您不知道,您的自定义类的动态属性将无法与 DataGridView 一起使用,因为 DGV 读取它们的方式。所以我这里的实现仅限于PropertyGrid。 Trying to use DataGridView together with ICustomTypeDescriptor

    3. 决定 PropertyGrid 组合框是否应该是可编辑的。 How do I add an editable combobox to a System.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; }
        }
    
    1. 您的自定义 PropertyDescriptor 需要保留对您的自定义属性的引用(例如下面的 m_Property)。它还必须重写 PropertyType 以返回与 A) 没有下拉列表时自定义类的类型相关联的类型,或 B) 您的 StringConverter 的下拉装饰子类。
        public override Type PropertyType { get { return m_Property.Type; } }
    
    

    我在我的自定义属性类上使用 Type 属性来做出决定:

        public Type Type
        {
            get
            {
                if (IsDropDownEnabled)
                    return typeof(DecoratedDropdown);
                else
                    return typeof(this);
            }
        }
    
    1. PropertyDescriptor 需要动态返回该属性的可选值列表,这是我存储在自定义属性类中的列表。我无法告诉你用 List 表示可选值是否有效。
        public ICollection Options { get { dynamic dObj = m_Property; return dObj.PossibleValues; } }
    
    1. 您的自定义类需要具有完整的 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; }
    
    

    如果我错过了什么,请告诉我。我最近做了这个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多