So ändern Sie PropertyGrid zur Laufzeit (Hinzufügen/Entfernen von Eigenschaften und dynamischen Typen/Aufzählungen)

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

Frage

Wie kann man ein Propertygrid zur Laufzeit in jeder Hinsicht ändern?Ich möchte in der Lage sein, Eigenschaften hinzuzufügen und zu entfernen und „dynamische Typen“ hinzuzufügen. Damit meine ich einen Typ, der mithilfe eines TypeConverters zu einem zur Laufzeit generierten Dropdown im Propertygrid führt.

Ich war tatsächlich in der Lage, beide Dinge zu tun (Eigenschaften hinzufügen/entfernen und dynamischen Typ hinzufügen), aber nur getrennt, nicht gleichzeitig.

Um die Unterstützung zum Hinzufügen und Entfernen von Eigenschaften zur Laufzeit zu implementieren, habe ich verwendet dieser Codeprojekt-Artikel und den Code ein wenig modifiziert, um verschiedene Typen (nicht nur Strings) zu unterstützen.

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

usw...

public enum CaptionPosition
{
    Top,
    Left
}

Meine Komplettlösung kann heruntergeladen werden Hier.

Es funktioniert gut, wenn ich Strings, Bools oder Enumerationen hinzufüge, aber wenn ich versuche, einen „dynamischen Typ“ wie StatesList hinzuzufügen, funktioniert es nicht.Weiß jemand warum und kann mir bei der Lösung helfen?

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

Die Methode, einen TypeConverter zu verwenden, funktioniert gut, wenn Sie beispielsweise nicht versuchen, die Eigenschaft zur Laufzeit hinzuzufügen diesen Code funktioniert problemlos, aber ich möchte beides können.

Bitte werfen Sie einen Blick darauf Mein Projekt.Danke!

War es hilfreich?

Lösung

Was Sie tun, ist das Hinzufügen von StatesList (a Typeconverter) als Eigenschaft.
Was Sie tun sollten, ist eine Eigenschaft mit StatesList als Typeconverter hinzuzufügen.

Andere Tipps

Ah, natürlich!

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

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

Funktioniert wie ein Zauber, danke!

Ich habe mein Projekt aktualisiert, hoffen, dass es für andere hilfreich sein kann, kann es hier .

Diese Frage und Antwort war für mich von großem Nutzen.Allerdings musste ich die Dinge noch etwas erweitern, indem ich zur Laufzeit generierte Dropdown-Listenwerte zuließ.Ich dachte, ich würde einen Beispielcode in Bezug auf die Anforderungen posten, falls ihn jemand nützlich findet.

Zuerst habe ich dem CustomProperty-Konstruktor einen Optionsparameter und eine Optionseigenschaft hinzugefügt:

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

Zweitens habe ich der CustomPropertyDescriptor-Klasse eine Optionseigenschaft hinzugefügt:

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

Drittens musste ich die GetStandardValues-Methode in meiner dynamischen Typklasse ändern (d. h.StatesList), um die neue Options-Eigenschaft für das CustomPropertyDescriptor-Objekt zu verwenden:

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

Schließlich musste ich beim Erstellen eines neuen CustomProperty-Objekts meine Optionsliste übergeben:

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

Anstelle der statischen Liste, die ich für dieses Beispiel übergeben habe, können Sie die Liste der Optionen für Ihr Dropdown-Menü auf beliebige Weise erstellen und haben so die volle Kontrolle über die verfügbaren Optionen.

in meinem Fall Typeconverter galt nicht Klasse Staaten

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

so hinzugefügt i Überschreibung in CustomPropertyDescriptor

public override TypeConverter Converter
{
    get {
        if (this.PropertyType.Equals(typeof(States)) ) {
            return new StatesList(); ; 
        }
        return base.Converter;
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top