, Но в других местах свойство - это просто свойства, а модель компонента не используется. Самое простое - посмотреть, работает ли оно для вашего приложения.

я есть класс, который программист может использовать для динамического добавления новых свойств. Для этого он реализуетICustomTypeDescriptor быть в состоянии переопределитьGetProperties() метод.

public class DynamicProperty
{
    public object Value { get; set; }

    public Type Type { get; set; }

    public string Name { get; set; }

    public Collection<Attribute> Attributes { get; set; }
}

public class DynamicClass : ICustomTypeDescriptor
{
    // Collection to code add dynamic properties
    public KeyedCollection<string, DynamicProperty> Properties
    {
        get;
        private set;
    }

    // ICustomTypeDescriptor implementation
    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
        // Properties founded within instance
        PropertyInfo[] instanceProps = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        // Fill property collection with founded properties
        PropertyDescriptorCollection propsCollection = 
            new PropertyDescriptorCollection(instanceProps.Cast<PropertyDescriptor>().ToArray());

        // Fill property collection with dynamic properties (Properties)
        foreach (var prop in Properties)
        {
            // HOW TO?
        }

        return propsCollection;
    }
}

Можно ли перебрать список свойств, чтобы добавить каждое свойство вPropertyDescriptorCollection?

В основном я хочу, чтобы программист мог добавитьDynamicProperty в коллекцию, которая будет обрабатыватьсяGetProperties, Что-то вроде:

new DynamicClass()
{
    Properties = {
        new DynamicProperty() {
            Name = "StringProp",
            Type = System.String,
            Value = "My string here"
        },

        new DynamicProperty() {
            Name = "IntProp",
            Type = System.Int32,
            Value = 10
        }
    }
}

Теперь теProperties будет установлен в свойствах экземпляра всякий раз, когдаGetPropertiesназывается. Я думаю, что это правильный путь?

Ответы на вопрос(1)

Решение Вопроса

PropertyDescriptorCollection propsCollection = 
            new PropertyDescriptorCollection(instanceProps.Cast<PropertyDescriptor>().ToArray());

Но создаваемая коллекция имеет только существующие свойства, а не новые.

Вам необходимо предоставить один массив, объединенный из существующих свойств и ваших новых свойств.

Что-то вроде этого:

instanceProps.Cast<PropertyDescriptor>().Concat(customProperties).ToArray()

Следующая проблема: вам нужноcustomProperties которая является коллекциейPropertyDescriptor, к несчастьюPropertyDescriptor это абстрактный класс, поэтому у вас нет простого способа его создать.

Мы можем исправить это, просто определите свой собственныйCustomPropertyDescriptor класс, производный отPropertyDescriptor и реализовать все абстрактные методы.

Что-то вроде этого:

public class CustomPropertyDescriptor : PropertyDescriptor
{
    private Type propertyType;
    private Type componentType;

    public CustomPropertyDescriptor(string propertyName, Type propertyType, Type componentType)
        : base(propertyName, new Attribute[] { })
    {
        this.propertyType = propertyType;
        this.componentType = componentType;
    }

    public override bool CanResetValue(object component) { return true; }
    public override Type ComponentType { get { return componentType; } }
    public override object GetValue(object component) { return 0; /* your code here to get a value */; }
    public override bool IsReadOnly { get { return false; } }
    public override Type PropertyType { get { return propertyType; } }
    public override void ResetValue(object component) { SetValue(component, null); }
    public override void SetValue(object component, object value) { /* your c,ode here to set a value */; }
    public override bool ShouldSerializeValue(object component) { return true; }
}

Я не заполнял звонки, чтобы получить и установить ваши свойства; эти вызовы зависят от того, как вы реализовали динамические свойства под капотом.

Затем вам нужно создать массивCustomPropertyDescriptor заполнить информацией, соответствующей вашим динамическим свойствам, и объединить ее с основными свойствами, как я описал вначале.

PropertyDescriptor не толькоописывает ваши свойства, он также позволяет клиенту на самом деле получить и установить значения этих свойств. И в этом весь смысл, не правда ли!

 Joao29 мая 2011 г., 09:32
propertyType правильный тип самой собственности? Что насчет componentType? Это тип объекта, где находится свойство?
 Rick Sladkey29 мая 2011 г., 09:37
propertyType тип динамического свойства. Если у вас есть динамическое целочисленное свойство, называемоеCount, это было быtypeof(int),componentType тип класса, который имеет динамические свойства, например,typeof(MyDynamicPropertyClass).
 Rick Sladkey29 мая 2011 г., 18:13
К сожалению нет. Реализация динамических свойств, подобных этому, работает только тогда, когда клиент (сущность фактически ищет, читает и записывает свойства) поддерживаетTypeDescriptor способ делать вещи. Это иногда называют «компонентной моделью», и не все потребители недвижимости поддерживают ее. Например, WPFделает поддержать его, например, для привязки данных. Также WinForms поддерживает компонентную модель дляPropertyGrid, Но в других местах свойство - это просто свойства, а модель компонента не используется. Самое простое - посмотреть, работает ли оно для вашего приложения.
 Joao29 мая 2011 г., 09:40
Еще один вопрос. Таким образом, если свойство, ранее добавленное черезProperties список, динамически доступ (используяvar например) могу ли я быть уверен, чтоGetProperties() используется для доступа к указанному свойству?

Ваш ответ на вопрос