Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a WinForms PropertyGrid to edit a list of strings?

Tags:

In my application I have a property grid to allow users to change settings. This works fine for strings and other value properties, but what I need now is a list of strings that can be edited by users.

The problem is that if I have MyPropertyGrid.SelectedObject = new { Test = new List<string>() }; in my code and the user attempts to edit the Test property, when they click on the Add button, the following error occurs:

 Constructor on type 'System.String' not found 

This makes sense as strings are immutable. However, I still need some way to store multiple strings (or string-like data) in a property grid.

Does anyone have any ideas on how I can accomplish this?

like image 527
KallDrexx Avatar asked Jun 10 '11 13:06

KallDrexx


1 Answers

Yes, you can specify an System.ComponentModel.Editor attribute on your list of strings, with StringCollectionEditor as the editor. You need to add a reference to System.Design.Dll to your project, in order for this to compile.

Example, suppose your object is like this:

[DefaultProperty("Name")] public class CustomObject {     [Description("Name of the thing")]     public String Name { get; set; }      [Description("Whether activated or not")]     public bool Activated { get; set; }      [Description("Rank of the thing")]     public int Rank { get; set; }      [Description("whether to persist the settings...")]     public bool Ephemeral { get; set; }      [Description("extra free-form attributes on this thing.")]     [Editor(@"System.Windows.Forms.Design.StringCollectionEditor," +         "System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",        typeof(System.Drawing.Design.UITypeEditor))]     [TypeConverter(typeof(CsvConverter))]     public List<String> ExtraStuff     {         get         {             if (_attributes == null)                 _attributes = new List<String>();             return _attributes;         }     }     private List<String> _attributes; } 

The property grid for that looks like this:

enter image description here

Click on the ... and you get:

enter image description here

If you don't like the builtin collection editor, you can implement your own custom collection editor.

My example shows the use of a TypeConverter attribute. If you don't do that, then the list displays in the prop grid as "(Collection)". The TypeConverter gets it to display as something intelligent. For example, to display a short string representation of the collection in the property grid, like this:

enter image description here

...the TypeConverter is like this:

public class CsvConverter : TypeConverter {     // Overrides the ConvertTo method of TypeConverter.     public override object ConvertTo(ITypeDescriptorContext context,        CultureInfo culture, object value, Type destinationType)     {         List<String> v = value as List<String>;         if (destinationType == typeof(string))         {             return String.Join(",", v.ToArray());          }         return base.ConvertTo(context, culture, value, destinationType);     } } 

You don't need a setter on the List<String>, because the collection editor doesn't set that property, it merely adds or removes entries to the property. So just provide the getter.

like image 156
Cheeso Avatar answered Sep 19 '22 06:09

Cheeso