【问题标题】:What's the correct way to edit a collection in a property grid在属性网格中编辑集合的正确方法是什么
【发布时间】:2011-05-07 21:59:20
【问题描述】:

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

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

其中一个错误的方式是这样的:

set not being called when editing a collection

用户 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
    }
}

【问题讨论】:

    标签: c# propertygrid


    【解决方案1】:

    这是一个有点棘手的问题;该解决方案涉及使用完整的 .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<SomeType>)result;
    
            return result;
        }
    }
    

    然后你必须用EditorAttribute装饰你的财产:

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

    是的,冗长而令人费解,但它确实有效。在集合编辑器弹出窗口中单击“确定”后,您可以再次打开它,值将保留。

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

    【讨论】:

      【解决方案2】:

      只要该类型有一个公共的无参数构造函数它应该可以工作:

      using System;
      using System.Collections.Generic;
      using System.Windows.Forms;
      class Foo {
          private readonly List<Bar> bars = new List<Bar>();
          public List<Bar> 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()
              }}});
          }
      }
      

      【讨论】:

      • 问题是get返回的集合只是从其他一些数据构建的临时集合。我将编辑我的问题。
      猜你喜欢
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2015-10-07
      相关资源
      最近更新 更多