Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用自定义属性在propertygrid中添加动态组合框属性?_C#_Winforms_Wpf Controls_Propertygrid - Fatal编程技术网

C# 如何使用自定义属性在propertygrid中添加动态组合框属性?

C# 如何使用自定义属性在propertygrid中添加动态组合框属性?,c#,winforms,wpf-controls,propertygrid,C#,Winforms,Wpf Controls,Propertygrid,我必须根据一些动作在propertygrid中创建一些动态属性。我能够按照下面的示例创建动态属性。但是我还需要在propertygrid中添加一个组合框。为此,我创建了一个从stringConverter派生的类。如下图所示: public class FormatStringConverter : StringConverter { public override Boolean GetStandardValuesSupported(ITypeDescriptorContext co

我必须根据一些动作在propertygrid中创建一些动态属性。我能够按照下面的示例创建动态属性。但是我还需要在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);
    }
}

如果有人用其他类型转换器解决了这个问题,我会告诉你这是否有助于我的事业

这里可以参考Marc Gravell的例子。 我不得不调整其他人的代码以使下拉列表正常工作,如果这不是一个完整的列表,我深表歉意

  • 自定义类的GetConverter()方法应该只返回TypeDescriptor.GetConverter(这个为true)

  • 如果您不知道,自定义类的动态属性将无法与DataGridView一起使用,因为DGV是如何读取它们的。因此,我在这里的实现仅限于PropertyGrid

  • 决定PropertyGrid组合框是否应可编辑

  • 您的自定义属性Descriptor需要保留对自定义属性的引用(例如下面的m_属性)。它还必须重写PropertyType以返回与a)没有下拉菜单时自定义类的类型关联的类型,或B)StringConverter的下拉菜单修饰的子类关联的类型
  • 我在自定义属性类上使用类型属性来做出该决定:

        public Type Type
        {
            get
            {
                if (IsDropDownEnabled)
                    return typeof(DecoratedDropdown);
                else
                    return typeof(this);
            }
        }
    
  • PropertyDescriptor需要动态返回该属性的可选值列表,该列表存储在自定义属性类中。我无法告诉您用列表表示可选值是否有效
  • 您的自定义类需要有一个完整的TypeDescriptor实现
  • 如果我遗漏了什么,请告诉我。我最近做了这个

        // 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; }
        }
    
        public override Type PropertyType { get { return m_Property.Type; } }
    
    
        public Type Type
        {
            get
            {
                if (IsDropDownEnabled)
                    return typeof(DecoratedDropdown);
                else
                    return typeof(this);
            }
        }
    
        public ICollection Options { get { dynamic dObj = m_Property; return dObj.PossibleValues; } }
    
    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; }