Come modificare PropertyGrid in fase di runtime (aggiungere / rimuovere proprietà e tipi / enum dinamici)

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

Domanda

Come si modifica una proprietàgrid in fase di esecuzione in ogni modo? Voglio essere in grado di aggiungere e rimuovere proprietà e aggiungere "tipi dinamici", ciò che intendo con questo è un tipo che si traduce in un menu a discesa generato dal runtime nella proprietàgrid utilizzando un TypeConverter.

Sono stato effettivamente in grado di fare entrambe le cose (aggiungere / rimuovere proprietà e aggiungere tipo dinamico) ma solo separatamente non allo stesso tempo.

Per implementare il supporto per aggiungere e rimuovere proprietà in fase di esecuzione ho usato questo codeproject article e ha leggermente modificato il codice per supportare diversi tipi (non solo stringhe).

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

ecc ...

public enum CaptionPosition
{
    Top,
    Left
}

La mia soluzione completa può essere scaricata qui .

Funziona bene quando aggiungo stringhe, bool o enum, ma quando provo ad aggiungere un tipo "dinamico" " come StatesList non funziona. Qualcuno sa perché e mi può aiutare a risolverlo?

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

Il metodo di utilizzo di un TypeConverter funziona perfettamente quando non si tenta di aggiungere la proprietà in fase di esecuzione, ad esempio questo codice funziona senza problemi, ma voglio essere in grado di fare entrambi.

Dai un'occhiata a il mio progetto . Grazie!

È stato utile?

Soluzione

Quello che fai è aggiungere StatesList (un TypeConverter) come proprietà.
Quello che dovresti fare è aggiungere una proprietà con StatesList come TypeConverter.

Altri suggerimenti

Ah, certo!

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

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

Funziona come un incantesimo, grazie!

Ho aggiornato il mio progetto, spero che possa essere utile agli altri, può essere trovato qui .

Questa domanda e risposta mi sono state di grande utilità. Tuttavia, avevo bisogno di estendere ulteriormente le cose consentendo valori dell'elenco a discesa generati in fase di esecuzione. Ho pensato di pubblicare un codice di esempio in merito a ciò che richiedeva, nel caso qualcuno lo trovasse utile.

Innanzitutto, ho aggiunto un parametro options al costruttore CustomProperty e ho aggiunto una proprietà 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; }
    }

In secondo luogo, ho aggiunto una proprietà Opzioni alla classe CustomPropertyDescriptor:

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

In terzo luogo, ho dovuto modificare il metodo GetStandardValues ??nella mia classe di tipo dinamico (cioè StatesList) per utilizzare la nuova proprietà Options sull'oggetto CustomPropertyDescriptor:

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

Infine, ho dovuto passare il mio elenco di opzioni durante la creazione di un nuovo oggetto CustomProperty:

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

Al posto dell'elenco statico che ho passato per questo esempio, puoi generare l'elenco di opzioni per il tuo menu a discesa in qualsiasi modo tu voglia, dandoti il ??pieno controllo delle opzioni disponibili.

nel mio caso TypeConverter non si applicava alla classe States

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

quindi ho aggiunto l'override in CustomPropertyDescriptor

public override TypeConverter Converter
{
    get {
        if (this.PropertyType.Equals(typeof(States)) ) {
            return new StatesList(); ; 
        }
        return base.Converter;
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top