Comment modifier PropertyGrid à l'exécution (ajout / suppression de propriétés et de types / enums dynamiques)

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

Question

Comment modifiez-vous un propertygrid lors de l'exécution de toutes les manières? 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 un menu déroulant généré par le moteur d'exécution à l'aide d'un TypeConverter.

J'ai effectivement pu 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 la prise en charge de l'ajout et de la suppression de propriétés à l'exécution, j'ai utilisé this. CodeProject article et a légèrement modifié le code pour prendre en charge différents types (pas seulement les 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 ici .

Cela fonctionne bien lorsque j'ajoute des chaînes, des bools ou des énumérations, mais lorsque j'essaie 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 correctement lorsque vous n'essayez pas d'ajouter la propriété à l'exécution, par exemple ce code fonctionne sans problème, mais je souhaite pouvoir effectuer les deux.

Veuillez consulter mon projet . Merci!

Était-ce utile?

La solution

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.

Autres conseils

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, j'espère qu'il pourra être utile aux autres. Vous pouvez le trouver ici .

Cette question et cette réponse m'ont été d'une grande utilité. Cependant, je devais étendre un peu plus les choses en autorisant les valeurs de liste déroulante générées à l'exécution. Je pensais publier un exemple de code indiquant ce dont il avait besoin, au cas où quelqu'un le trouverait utile.

Tout d'abord, j'ai ajouté un paramètre d'options au constructeur CustomProperty, puis 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; }
    }

Deuxièmement, j'ai ajouté une propriété Options à la classe CustomPropertyDescriptor:

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

Troisièmement, je devais modifier la méthode GetStandardValues ??dans ma classe de types dynamiques (par exemple, StatesList) pour utiliser la nouvelle propriété Options de l'objet CustomPropertyDescriptor:

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

Enfin, je devais transmettre 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 transmise pour cet exemple, vous pouvez générer la liste d’options de votre liste déroulante de la manière qui vous convient, vous donnant ainsi un contrôle total sur les options disponibles.

dans mon cas, TypeConverter ne s'appliquait pas à la classe States

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

j'ai donc ajouté un remplacement dans CustomPropertyDescriptor

public override TypeConverter Converter
{
    get {
        if (this.PropertyType.Equals(typeof(States)) ) {
            return new StatesList(); ; 
        }
        return base.Converter;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top