2008-11-24 4 views
22

Comment modifier une grille de propriétés à l'exécution de toutes les manières possibles? Je veux pouvoir ajouter et supprimer des propriétés et ajouter des "types dynamiques", ce que je veux dire par là est un type qui résulte en une liste déroulante générée à l'exécution dans la grille de propriétés en utilisant un TypeConverter.Comment modifier PropertyGrid au moment de l'exécution (ajouter/supprimer des propriétés et des types dynamiques/enums)

J'ai effectivement été capable de faire ces deux choses (ajouter/supprimer des propriétés et ajouter un type dynamique) mais seulement séparément, pas en même temps.

Pour implémenter le support pour ajouter et supprimer des propriétés à l'exécution j'ai utilisé this codeproject article et modifié le code un peu pour supporter différents types (pas seulement des chaînes).

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 
} 

Ma solution complète peut être téléchargée here.

Cela fonctionne très bien quand j'ajoute des chaînes, des booléens ou des énumérations, mais quand j'essaye d'ajouter un "type dynamique" comme StatesList cela ne fonctionne pas. Est-ce que quelqu'un sait pourquoi et peut m'aider à le résoudre?

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; 
    } 
} 

La méthode d'utilisation d'un TypeConverter fonctionne très bien lorsque vous ne cherchez pas à ajouter la propriété lors de l'exécution, par exemple this code fonctionne sans aucun problème, mais je veux être en mesure de faire les deux.

Veuillez jeter un coup d'œil à my project. Merci!

Répondre

7

Ce que vous faites est d'ajouter StatesList (un TypeConverter) en tant que propriété.
Ce que vous devez faire est d'ajouter une propriété avec StatesList en tant que TypeConverter.

5

Ah, bien sûr!

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

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

Fonctionne comme un charme, merci!

J'ai mis à jour mon projet, espérons qu'il peut être utile aux autres, il peut être trouvé here.

+0

Vous êtes bienvenus :) –

+0

Je sais que le poste est très vieux, mais je J'ai une petite question. J'utilise exactement votre code dans mon application, mais la liste déroulante personnalisée ne fonctionne pas. Le nom de la propriété est grisé et aucune option n'est disponible. Une idée, ce que je peux faire pour résoudre ce problème? Merci à l'avance, Martin – user653427

+1

@ user653427, il pourrait également être utile pour poster une nouvelle question et lien Comme il est une vieille question de retour à cette page. Vous serez en mesure de donner plus de détails et d'atteindre plus de gens de cette façon. –

3

Cette question et réponse a été d'une grande utilité pour moi. Cependant, j'avais besoin d'étendre les choses un peu plus loin en tenant compte des valeurs des listes déroulantes générées au moment de l'exécution. J'ai pensé que je posterais un code d'exemple en ce qui concerne ce dont il a besoin, au cas où quelqu'un le trouverait utile.

D'abord, j'ajouté un paramètre options au constructeur CustomProperty et a ajouté une propriété Options:

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 second lieu, j'ai ajouté une propriété Options pour la classe CustomPropertyDescriptor:

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

Troisièmement, je a dû modifier la méthode GetStandardValues ​​dans ma classe de type dynamique (à savoirStatesList) à faire usage de la nouvelle propriété Options sur l'objet CustomPropertyDescriptor:

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

Enfin, je devais passer ma liste d'options lors de la création d'un nouvel objet CustomProperty:

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

Au lieu de la liste statique que j'ai passée pour cet exemple, vous pouvez générer la liste des options pour votre liste déroulante de la manière que vous voulez, vous donnant un contrôle total sur les options disponibles.

+0

merci de prendre le temps de développer la réponse, très utile. –

+0

qu'est-ce que valueType? son typeof (liste )? –

+0

C'est le type de la valeur de propriété transmise, qui peut être quelque chose comme string, int, ou un type personnalisé comme States (voir la réponse @ salle55). Vous pouvez utiliser typeof, comme vous l'avez indiqué ou peut-être quelque chose comme value.GetType(). – Scott

0

dans mon cas TypeConverter ne s'appliquait pas aux Etats classe

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

donc j'ajouté override CustomPropertyDescriptor

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