Как правильно редактировать коллекцию в сетке свойств?

2

У меня есть класс, который отображается в сетке свойств. Одним из свойств является List<SomeType>.

Какой простой/правильный способ настроить код, чтобы я мог добавлять и удалять элементы из этой коллекции через сетку свойств, предпочтительно используя стандартный CollectionEditor.

Один из неправильных способов:

не вызывается при редактировании коллекции

Пользовательские аннакаты показывают, что я открываю интерфейс 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
    }
}
Теги:
propertygrid

2 ответа

5
Лучший ответ

Это немного сложно. решение включает в себя построение с полной платформой .NET Framework (поскольку только клиентская инфраструктура не включает System.Design). Вам нужно создать свой собственный подкласс CollectionEditor и сообщить ему, что делать с временной коллекцией после того, как пользовательский интерфейс завершен с ним:

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.

  • 0
    Спасибо, это сработало нормально!
0

Пока тип имеет открытый конструктор без параметров, он должен просто работать:

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()
        }}});
    }
}
  • 0
    Дело в том, что возврат коллекции из get - это только временная коллекция, созданная из других данных. Я отредактирую свой вопрос.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню