在属性网格中编辑集合的正确方法是什么

我有一个显示在属性网格中的类。 其中一个属性是List

设置代码的最简单/最正确的方法是什么,以便我可以通过属性网格添加和删除此集合中的项目,最好使用标准的CollectionEditor

错误的方法之一是这样的:

编辑集合时未设置调用

用户annakata建议我公开IEnumerable接口而不是集合。 有人可以提供更多细节吗?

我有额外的复杂性, get返回的集合实际上并没有指向我的类中的成员,而是从其他成员动态构建,如下所示:

 public List Stuff { get { List stuff = new List(); //...populate stuff with data from an internal xml-tree return stuff; } set { //...update some data in the internal xml-tree using value } } 

这是一个有点棘手的问题; 解决方案涉及使用完整的.NET Framework构建(因为仅客户端框架不包括System.Design )。 您需要创建自己的CollectionEditor子类,并告诉它在UI完成后如何处理临时集合:

 public class SomeTypeEditor : CollectionEditor { public SomeTypeEditor(Type type) : base(type) { } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { object result = base.EditValue(context, provider, value); // assign the temporary collection from the UI to the property ((ClassContainingStuffProperty)context.Instance).Stuff = (List)result; return result; } } 

然后你必须使用EditorAttribute来装饰你的属性:

 [Editor(typeof(SomeTypeEditor), typeof(UITypeEditor))] public List Stuff { // ... } 

很长很复杂,是的,但它确实有效。 在集合编辑器弹出窗口中单击“确定”后,可以再次打开它,值将保留。

注意:您需要导入名称空间System.ComponentModelSystem.ComponentModel.DesignSystem.Drawing.Design

只要该类型具有公共无参数构造函数, 它就应该工作

 using System; using System.Collections.Generic; using System.Windows.Forms; class Foo { private readonly List bars = new List(); public List Bars { get { return bars; } } public string Caption { get; set; } } class Bar { public string Name { get;set; } public int Id { get; set; } } static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.Run(new Form { Controls = { new PropertyGrid { Dock = DockStyle.Fill, SelectedObject = new Foo() }}}); } }