【问题标题】:How can I use a WinForms PropertyGrid to edit a list of strings?如何使用 WinForms PropertyGrid 编辑字符串列表?
【发布时间】:2026-02-11 00:55:02
【问题描述】:

在我的应用程序中,我有一个属性网格允许用户更改设置。这适用于字符串和其他值属性,但我现在需要的是用户可以编辑的字符串列表。

问题是,如果我的代码中有MyPropertyGrid.SelectedObject = new { Test = new List<string>() };,并且用户尝试编辑Test 属性,当他们单击“添加”按钮时,会出现以下错误:

 Constructor on type 'System.String' not found

这是有道理的,因为字符串是不可变的。但是,我仍然需要一些方法在属性网格中存储多个字符串(或类似字符串的数据)。

有人对我如何实现这一点有任何想法吗?

【问题讨论】:

  • 试试这个,MyPropertyGrid.SelectedObjec = Test //它会在按钮点击时返回字符串列表 在Test属性中设置字符串列表....
  • 我不确定您要尝试什么,因为您的代码似乎被注释格式吞噬了。

标签: c# string winforms propertygrid


【解决方案1】:

是的,您可以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 属性的使用。如果您不这样做,则列表在道具网格中显示为“(集合)”。类型转换器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&lt;String&gt; 上不需要设置器,因为集合编辑器不设置该属性,它只是添加或删除该属性的条目。所以只需提供吸气剂。

【讨论】:

  • 太棒了,第一种方法就像一个魅力(字符串集合编辑器应该可以很好地满足我的需要)。非常感谢:)
  • 优秀的答案!
【解决方案2】:

如果您只需要一个字符串容器,只需使用:BindingList&lt;string&gt; 而不是 list&lt;string&gt;

编辑器是自动创建的。

此外,来回“投射”到List&lt;T&gt; 很容易。 从 List 到 BindingList 只需使用 bList = BindingList(orignalList) 构造函数(如果出现只读错误 - 将列表一一插入)。要获取列表,您可以使用.ToList() 扩展方法。

【讨论】:

    【解决方案3】:

    属性声明遗漏了一个重要属性: [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

    没有它,设计器不会序列化集合数据。

    【讨论】:

    • 如果您使用绑定列表,即 BindingList,它可以在没有属性的情况下工作