Search code examples
c#arrayspropertygrid

Constructor not found for String


If I have an object in a property grid containing a List<string[]> or Dictionary<string,string[]>(using GenericDictionaryEditor), when I click on the detail beside the property and click add, a message pops up saying that no constructor can be found (for the list) or no parameterless constructor found (for the dictionary). I don't understand editors or the property grid really, and any help would be appreciated.

[DataMember(Name="FolderPaths")]
[ReadOnly(false)]
[Description("List of folder paths")]
[Editor(typeof(Wexman.Design.GenericDictionaryEditor<string, string[]>), typeof(UITypeEditor))]
[Wexman.Design.GenericDictionaryEditor(Title="Folder Paths")]
public Dictionary<string, string[]> FolderPaths { get; set; }

This one says constructor not found for System.string[].

[DataMember(Name="FolderPaths")]
[ReadOnly(false)]
[Description("List of folder paths")]
public List<string[]> FolderPaths { get; set; }

Solution

  • One solution is to register a TypeDescriptionProvider for the string[] type. Here is the sample code (you need to register this at the beginning of your program, before displaying any property grid):

    ...
    TypeDescriptor.AddProvider(new StringArrayDescriptionProvider(), typeof(string[]));
    ...
    

    And here is the StringArrayDescriptionProvider code:

    public class StringArrayDescriptionProvider : TypeDescriptionProvider
    {
        private static TypeDescriptionProvider _baseProvider;
    
        static StringArrayDescriptionProvider()
        {
           // get default metadata
            _baseProvider = TypeDescriptor.GetProvider(typeof(string[]));
        }
    
        public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
        {
            // this is were we define create the instance
            // NB: .NET could do this IMHO...
            return Array.CreateInstance(typeof(string), 0);
        }
    
        public override IDictionary GetCache(object instance)
        {
            return _baseProvider.GetCache(instance);
        }
    
        public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
        {
            return _baseProvider.GetExtendedTypeDescriptor(instance);
        }
    
        public override string GetFullComponentName(object component)
        {
            return _baseProvider.GetFullComponentName(component);
        }
    
        public override Type GetReflectionType(Type objectType, object instance)
        {
            return _baseProvider.GetReflectionType(objectType, instance);
        }
    
        public override Type GetRuntimeType(Type reflectionType)
        {
            return _baseProvider.GetRuntimeType(reflectionType);
        }
    
        public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
        {
            return _baseProvider.GetTypeDescriptor(objectType, instance);
        }
    
        public override bool IsSupportedType(Type type)
        {
            return _baseProvider.IsSupportedType(type);
        }
    }
    

    This is how it will look: enter image description here