C# 什么';这是在属性网格中编辑集合的正确方法

C# 什么';这是在属性网格中编辑集合的正确方法,c#,propertygrid,C#,Propertygrid,我有一个显示在属性网格中的类。其中一个属性是列表 设置代码的最简单/正确方法是什么,以便我可以通过属性网格添加和删除此集合中的项目,最好使用标准的CollectionEditor 一种错误的方法是这样的: public List<SomeType> Stuff { get { List<SomeType> stuff = new List<SomeType>(); //...populate stuff with

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

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

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

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

用户annakata建议我公开一个
IEnumerable
接口,而不是一个集合。有人能给我提供更多的细节吗

我还有一个额外的复杂性,就是
get
返回的集合实际上并不指向我的类中的某个成员,而是从另一个成员动态生成的,如下所示:

public List<SomeType> Stuff
{
    get
    {
        List<SomeType> stuff = new List<SomeType>();
        //...populate stuff with data from an internal xml-tree
        return stuff;
    }
    set
    {
        //...update some data in the internal xml-tree using value
    }
}
公共列表内容
{
得到
{
列表内容=新列表();
//…使用内部xml树中的数据填充内容
归还物品;
}
设置
{
//…使用值更新内部xml树中的某些数据
}
}

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

使用系统;
使用System.Collections.Generic;
使用System.Windows.Forms;
福班{
私有只读列表栏=新列表();
公共列表栏{获取{返回栏;}}
公共字符串标题{get;set;}
}
分类栏{
公共字符串名称{get;set;}
公共int Id{get;set;}
}
静态类程序{
[状态线程]
静态void Main(){
Application.EnableVisualStyles();
Application.Run(新表单{
控件={new PropertyGrid{Dock=DockStyle.Fill,
SelectedObject=newfoo()
}}});
}
}

这是一个有点棘手的问题;解决方案涉及使用完整的.NET框架进行构建(因为仅客户端的框架不包括
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<SomeType>)result;

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


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

问题是,从
get
返回的集合仅是从其他一些数据构建的临时集合。我将编辑我的问题。
[Editor(typeof(SomeTypeEditor), typeof(UITypeEditor))]
public List<SomeType> Stuff {
    // ...
}