.Net grade de propriedade. Existe uma maneira de deixar a grade manipular objeto de maneira diferente

StackOverflow https://stackoverflow.com/questions/931644

Pergunta

Como eu entendi, a grade propriedade é dado um objeto que ele pode manipular, extraindo suas propriedades usando reflexões.

O meu problema é que eu tenho um conjunto de parâmetros que é determinado durante o tempo de execução, portanto, eu não posso staticly compor uma classe com propriedades para representar este conjunto.

Eu tenho dois idéia em mente para resolver este problema, mas ambos são complexas e provavelmente irá consumir muito tempo, de facto eu vou dizer que eles não são práticos sob minhas limitações de tempo. Uma é usar reflexão emitir, a fim de definir uma classe dinamicamente ea outra é construir dynamiclly um arquivo C # fonte e, em seguida, compilá-lo usando CodeDom.

Can Propriedade grade se comportam de maneira diferente (outro então extrair as propriedades de um objeto usando reflexões) que pode atendam o meu problema?

Se não sabe qualquer outro controle que pode fazer o trabalho para mim?

Eu quero dizer que a razão que eu fui para a grade de propriedade desde o início foi a sua capacidade de fornecer realy nice recuperação de dados UI para a cor types.For comum você autometically obter uma paleta, Para DataTime você automaticamente tem um calendário agradável. Gostaria de obter essas coisas automaticamente, se possível.

Foi útil?

Solução

Sim, PropertyGrid pode mostrar coisas outros do que apenas as propriedades de tempo de compilação, usando qualquer um dos TypeConverter, ICustomTypeDescriptor ou TypeDescriptionProvider para fornecer tempo de execução pseudo-propriedades. Pode dar um exemplo do que os seus parâmetros parece? Eu deveria ser capaz de fornecer um exemplo ...


aqui está um exemplo básico (tudo é string, etc) com base em um resposta anterior (relacionado, mas diferente):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
class PropertyBagPropertyDescriptor : PropertyDescriptor {
    public PropertyBagPropertyDescriptor(string name) : base(name, null) { }
    public override object GetValue(object component) {
        return ((PropertyBag)component)[Name];
    }
    public override void SetValue(object component, object value) {
        ((PropertyBag)component)[Name] = (string)value;
    }
    public override void ResetValue(object component) {
        ((PropertyBag)component)[Name] = null;
    }
    public override bool CanResetValue(object component) {
        return true;
    }
    public override bool ShouldSerializeValue(object component)
    { // *** this controls whether it appears bold or not; you could compare
      // *** to a default value, or the last saved value...
        return ((PropertyBag)component)[Name] != null;
    }
    public override Type PropertyType {
        get { return typeof(string); }
    }
    public override bool IsReadOnly {
        get { return false; }
    }
    public override Type ComponentType {
        get { return typeof(PropertyBag); }
    }
}
[TypeConverter(typeof(PropertyBagConverter))]
class PropertyBag {
    public string[] GetKeys() {
        string[] keys = new string[values.Keys.Count];
        values.Keys.CopyTo(keys, 0);
        Array.Sort(keys);
        return keys;
    }
    private readonly Dictionary<string, string> values
        = new Dictionary<string, string>();
    public string this[string key] {
        get {
            string value;
            values.TryGetValue(key, out value);
            return value;
        }
        set {
            if (value == null) values.Remove(key);
            else values[key] = value;
        }
    }
}
// has the job of (among other things) providing properties to the PropertyGrid
class PropertyBagConverter : TypeConverter {
    public override bool GetPropertiesSupported(ITypeDescriptorContext context) {
        return true; // are we providing custom properties from here?
    }
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, System.Attribute[] attributes) {
        // get the pseudo-properties
        PropertyBag bag = (PropertyBag)value;
        string[] keys = bag.GetKeys();
        PropertyDescriptor[] props = Array.ConvertAll(
            keys, key => new PropertyBagPropertyDescriptor(key));
        return new PropertyDescriptorCollection(props, true);
    }
}

static class Program {
    [STAThread]
    static void Main() { // demo form app
        PropertyBag bag = new PropertyBag();
        bag["abc"] = "def";
        bag["ghi"] = "jkl";
        bag["mno"] = "pqr";
        Application.EnableVisualStyles();
        Application.Run(
            new Form {
                Controls = { new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = bag
                }}
            });
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top