在我的应用程序中,我有一个属性网格,允许用户更改设置。这适用于字符串和其他值属性,但我现在需要的是一个可由用户编辑的字符串列表。
问题是,如果我的代码中有MyPropertyGrid.SelectedObject = new { Test = new List<string>() };
并且用户尝试编辑Test
属性,则当他们单击“添加”按钮时,会出现以下错误:
Constructor on type 'System.String' not found
这是有道理的,因为字符串是不可变的。但是,我仍然需要一些方法来在属性网格中存储多个字符串(或类似字符串的数据)。
有没有人对如何做到这一点有任何想法?
答案 0 :(得分:43)
是的,你可以specify an System.ComponentModel.Editor
attribute on your list of strings, with StringCollectionEditor
as the editor。您需要向项目添加对System.Design.Dll的引用,以便进行编译。
示例,假设您的对象是这样的:
[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;
}
该属性网格如下所示:
点击...
即可获得:
如果您不喜欢内置集合编辑器you can implement your own custom collection editor。
我的示例显示了TypeConverter属性的使用。如果您不这样做,则列表在道具网格中显示为“(收藏)”。 TypeConverter gets it to display as something intelligent。例如,要在属性网格中显示集合的短字符串表示形式,如下所示:
... TypeConverter是这样的:
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);
}
}
您不需要List<String>
上的setter,因为集合编辑器不设置该属性,它只是添加或删除属性的条目。所以只需提供吸气剂。
答案 1 :(得分:7)
如果您只需要一个字符串容器,只需使用:BindingList<string>
而不是list<string>
自动创建编辑器。
此外,来回List<T>
来回“轻松”。
从List到BindingList只需使用bList = BindingList(orignalList)
构造函数(如果你得到只读错误 - 逐个插入列表)。要获取列表,您可以使用.ToList()
扩展方法。
答案 2 :(得分:3)
财产声明遗漏了一个重要的属性:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
如果没有它,设计师不会序列化收集数据。