2008-11-24 16 views
22

¿Cómo se modifica una propiedad cuadrícula en tiempo de ejecución en todos los sentidos? Quiero poder agregar y eliminar propiedades y agregar "tipos dinámicos", lo que quiero decir con que es un tipo que da como resultado un menú desplegable generado en tiempo de ejecución en la propiedad grid usando un TypeConverter.Cómo modificar PropertyGrid en tiempo de ejecución (agregar/eliminar propiedades y tipos dinámicos/enumeraciones)

En realidad, he podido hacer ambas cosas (agregar/eliminar propiedades y agregar tipo dinámico) pero solo por separado, no al mismo tiempo.

Para implementar el soporte para agregar y eliminar propiedades en tiempo de ejecución usé this codeproject article y modifiqué un poco el código para admitir diferentes tipos (no solo cadenas).

private System.Windows.Forms.PropertyGrid propertyGrid1; 
private CustomClass myProperties = new CustomClass(); 

public Form1() 
{ 
    InitializeComponent(); 

    myProperties.Add(new CustomProperty("Name", "Sven", typeof(string), false, true)); 
    myProperties.Add(new CustomProperty("MyBool", "True", typeof(bool), false, true)); 
    myProperties.Add(new CustomProperty("CaptionPosition", "Top", typeof(CaptionPosition), false, true)); 
    myProperties.Add(new CustomProperty("Custom", "", typeof(StatesList), false, true)); //<-- doesn't work 
} 

/// <summary> 
/// CustomClass (Which is binding to property grid) 
/// </summary> 
public class CustomClass: CollectionBase,ICustomTypeDescriptor 
{ 
    /// <summary> 
    /// Add CustomProperty to Collectionbase List 
    /// </summary> 
    /// <param name="Value"></param> 
    public void Add(CustomProperty Value) 
    { 
     base.List.Add(Value); 
    } 

    /// <summary> 
    /// Remove item from List 
    /// </summary> 
    /// <param name="Name"></param> 
    public void Remove(string Name) 
    { 
     foreach(CustomProperty prop in base.List) 
     { 
      if(prop.Name == Name) 
      { 
       base.List.Remove(prop); 
       return; 
      } 
     } 
    } 

etc ...

public enum CaptionPosition 
{ 
    Top, 
    Left 
} 

Mi solución completa se puede descargar here.

Funciona bien cuando agrego cadenas, bools o enums, pero cuando intento agregar un "tipo dinámico" como StatesList, no funciona. ¿Alguien sabe por qué y puede ayudarme a resolverlo?

public class StatesList : System.ComponentModel.StringConverter 
{ 
    private string[] _States = { "Alabama", "Alaska", "Arizona", "Arkansas" }; 

    public override System.ComponentModel.TypeConverter.StandardValuesCollection 
    GetStandardValues(ITypeDescriptorContext context) 
    { 
     return new StandardValuesCollection(_States); 
    } 

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
    { 
     return true; 
    } 

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
} 

El método de uso de un TypeConverter funciona bien cuando no se intenta añadir la propiedad en tiempo de ejecución, por ejemplo this code funciona sin ningún problema, pero yo quiero ser capaz de hacer ambas cosas.

Por favor, eche un vistazo a my project. Gracias!

Respuesta

7

Lo que hace es agregar StatesList (TypeConverter) como una propiedad.
Lo que debe hacer es agregar una propiedad con StatesList como TypeConverter.

5

¡Ah, por supuesto!

myProperties.Add(new CustomProperty("Custom", "", typeof(States), false, true)); 

[TypeConverter(typeof(StatesList))] 
public class States 
{ 
} 

¡Funciona como un encanto, gracias!

He actualizado mi proyecto, espero que pueda ser útil para otros, se puede encontrar here.

+0

que estés :) recepción –

+0

sé que el mensaje es muy antiguo, pero tener una breve pregunta Utilizo exactamente su código dentro de mi aplicación pero el combobox personalizado no funciona. El nombre de la propiedad está atenuado y no hay opciones disponibles. Alguna idea, ¿qué puedo hacer para arreglar eso? Gracias de antemano, Martin – user653427

+1

@ user653427, ya que esta es una vieja pregunta, también podría valer la pena para fijar una nueva pregunta y el enlace a esta página. Podrás dar más detalles y llegar a más personas de esa manera. –

3

Esta pregunta y respuesta fue de gran utilidad para mí. Sin embargo, necesitaba extender las cosas un poco más al permitir valores de lista desplegable generados en tiempo de ejecución. Pensé que publicaría un código de muestra con respecto a lo que requería, en caso de que alguien lo encuentre útil.

En primer lugar, he añadido un parámetro de opciones para el constructor CustomProperty y ha añadido una propiedad Opciones:

private List<string> lOptions; 

    public CustomProperty(string sName, object value, Type tType, bool bReadOnly, bool bVisible, List<string> lOptions) 
    { 
     this.lOptions = lOptions; 
    } 

    public List<string> Options 
    { 
     get { return lOptions; } 
    } 

En segundo lugar, he añadido una propiedad Opciones de la clase CustomPropertyDescriptor:

public List<string> Options 
    { 
     get 
     { 
      return m_Property.Options; 
     } 
    } 

En tercer lugar, tuve que modificar el método GetStandardValues ​​en mi clase de tipo dinámico (es decir,StatesList) para hacer uso de la nueva propiedad Opciones en el objeto CustomPropertyDescriptor:

public override StandardValuesCollection 
       GetStandardValues(ITypeDescriptorContext context) 
    { 
     CustomPropertyDescriptor descriptor = (CustomPropertyDescriptor)context.PropertyDescriptor; 
     return new StandardValuesCollection(descriptor.Options); 
    } 

Finalmente, tuve que pasar en mi lista de opciones cuando se crea un nuevo objeto CustomProperty:

List<string> optionsList = new List<string>(new string[] { "test1", "test2", "test3" });   
    CustomProperty myProperty = new CustomProperty(attr.Name, attr.Value, valueType, false, true, optionsList); 

En lugar de En la lista estática que pasé para este ejemplo, puede generar la lista de opciones para su menú desplegable de la forma que desee, dándole control total sobre las opciones disponibles.

+0

gracias por tomarse el tiempo para ampliar la respuesta, muy útil. –

+0

¿qué es valueType? su typeof (enumere )? –

+0

Es el tipo de valor de propiedad que se pasa, que podría ser algo como string, int o un tipo personalizado como States (vea la respuesta de @ salle55). Podría usar typeof, como usted indicó o tal vez algo así como value.GetType(). – Scott

0

en mi caso TypeConverter no se aplicaba a la clase Unidos

[TypeConverter(typeof(StatesList))] // not work 
public class States 
{ 
} 

por lo que añade anulación en CustomPropertyDescriptor

public override TypeConverter Converter 
{ 
    get { 
     if (this.PropertyType.Equals(typeof(States))) { 
      return new StatesList(); ; 
     } 
     return base.Converter; 
    } 
} 
Cuestiones relacionadas