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?
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:
Click on the ...
and you get:
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:
...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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With