Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
478 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...