Search code examples
c#winformsjson.netpropertygrid

System.MissingMethodException when using propertyGrid


I have a class

class PartitionTemplate
{
    public PartitionTemplate()
    {
        keepLabels = new List<string>();
        partitions = new List<partition>();
    }
    [JsonProperty("keepLabels")]
    public List<String> keepLabels { get; set; }
    [JsonProperty("slot")]
    public int slot { get; set; }
    ....
}

my goal is to edit it with propertyGrid , using the following code:

    PartitionTemplate partiTemplate;
    //fi is FileInfo with the class as json using 
    //Newtonsoft.Json.JsonConvert.DeserializeObject<PartitionTemplate>(File.ReadAllText(partitionfile.FullName));
    PartitionTemplate.ReadOrCreatePartitonConfigurationFile(out partiTemplate, fi);
    propertyGrid1.SelectedObject = partiTemplate;

my problem is : when I try to add element to keepLabels i get the following error :

Exception thrown: 'System.MissingMethodException' in mscorlib.dll

Additional information: Constructor on type 'System.String' not found. 

how can it be fixed?


Solution

  • This happens because when you click the 'Add' button in the Collection Editor (a standard editor for the property grid) it creates a new item using a supposed public parameterless constructor, which doesn't exist on System.String (you can't do var s = new String();).

    What you can do though, if you want to keep the keepLabels property as is, is to create a custom editor, like this:

    // decorate the property with this custom attribute  
    [Editor(typeof(StringListEditor), typeof(UITypeEditor))]
    public List<String> keepLabels { get; set; }
    
    ....
    
    // this is the code of a custom editor class
    // note CollectionEditor needs a reference to System.Design.dll
    public class StringListEditor : CollectionEditor
    {
        public StringListEditor(Type type)
            : base(type)
        {
        }
    
        // you can override the create instance and return whatever you like
        protected override object CreateInstance(Type itemType)
        {
            if (itemType == typeof(string))
                return string.Empty; // or anything else
    
            return base.CreateInstance(itemType);
        }
    }