2008-11-24 7 views
22

Wie ändert man ein propertygrid zur Laufzeit in jeder Hinsicht? Ich möchte in der Lage sein, Eigenschaften hinzuzufügen und zu entfernen und "dynamische Typen" hinzuzufügen, was ich damit meine, ist ein Typ, der zu einem Laufzeit-erzeugten Dropdown in dem propertygrid führt, das einen TypeConverter verwendet.So ändern Sie PropertyGrid zur Laufzeit (Eigenschaft hinzufügen/entfernen und dynamische Typen/enums)

Ich konnte diese beiden Dinge tatsächlich tun (Eigenschaften hinzufügen/entfernen und dynamischen Typ hinzufügen), aber nur getrennt und nicht gleichzeitig.

Um die Unterstützung zum Hinzufügen und Entfernen von Eigenschaften zur Laufzeit zu implementieren, habe ich this codeproject article verwendet und den Code ein bisschen geändert, um verschiedene Typen (nicht nur Zeichenfolgen) 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; 
      } 
     } 
    } 

etc ...

public enum CaptionPosition 
{ 
    Top, 
    Left 
} 

Meine Komplettlösung here heruntergeladen werden.

Es funktioniert gut, wenn ich Strings, Bools oder Enums hinzufügen, aber wenn ich versuche, einen "dynamischen Typ" wie StatesList hinzuzufügen, funktioniert es nicht. Weiß jemand warum und kann mir helfen, es zu lösen?

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

Verfahren zur Herstellung eines Typeconverter mit funktioniert gut, wenn Sie nicht versuchen, die Eigenschaft zur Laufzeit hinzufügen, zum Beispiel this code funktioniert ohne Probleme, aber ich möchte in der Lage sein, beides zu tun.

Bitte werfen Sie einen Blick auf my project. Danke!

Antwort

7

Was Sie tun, ist das Hinzufügen von StatesList (ein TypeConverter) als eine Eigenschaft.
Was Sie tun sollten, ist das Hinzufügen einer Eigenschaft mit StatesList als TypeConverter.

5

Ah, natürlich!

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

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

Funktioniert wie ein Charme, danke!

Ich habe mein Projekt aktualisiert, hoffe, es kann für andere hilfreich sein, es kann here gefunden werden.

+0

Sie sind willkommen :) –

+0

Ich weiß, dass die Post ist sehr alt, aber ich habe eine kurze Frage. Ich benutze genau Ihren Code innerhalb meiner Anwendung, aber die benutzerdefinierte Combobox funktioniert nicht. Der Name der Eigenschaft ist ausgegraut und es sind keine Optionen verfügbar. Irgendeine Idee, was ich tun kann, um das zu beheben? Vielen Dank im Voraus, Martin – user653427

+1

@ user653427, Da dies so eine alte Frage ist, könnte es auch wert sein, eine neue Frage zu stellen und auf diese Seite verlinken. Sie können mehr Details angeben und mehr Menschen auf diese Weise erreichen. –

3

Diese Frage und Antwort war von großem Nutzen für mich. Allerdings musste ich die Dinge ein wenig erweitern, indem ich für die Laufzeit generierte Dropdown-Listenwerte berücksichtigte. Ich dachte mir, ich würde einen Beispielcode posten, um herauszufinden, was es benötigt, falls jemand es nützlich findet.

Zuerst habe ich ein Optionsparameter an die Custom Konstruktor hinzugefügt und hinzugefügt, um eine Eigenschaft 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; } 
    } 

Zweitens habe ich eine Eigenschaft Options auf die CustomPropertyDescriptor Klasse:

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

Drittens I Ich musste die GetStandardValues-Methode in meiner Klasse für dynamischen Typ ändern (d. hStatesList) Verwendung der neuen Options-Eigenschaft auf dem CustomPropertyDescriptor Objekt zu machen:

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

Schließlich hatte ich in meiner Liste der Optionen zu übergeben, wenn ein neues Custom Objekt erstellen:

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

Anstelle von In der statischen Liste, die ich für dieses Beispiel angegeben habe, können Sie die Liste der Optionen für Ihr Dropdown auf beliebige Weise generieren, wodurch Sie die volle Kontrolle über die verfügbaren Optionen haben.

+0

danke, dass Sie die Zeit nehmen, um auf die Antwort zu erweitern, sehr hilfreich. –

+0

Was ist ValueType? seine Art von (Liste )? –

+0

Es ist der Typ des übergebenen Eigenschaftswerts, der etwas wie string, int oder ein benutzerdefinierter Typ wie States sein kann (siehe @ salle55s Antwort). Sie könnten typeof verwenden, wie Sie angegeben haben, oder vielleicht etwas wie value.GetType(). – Scott

0

in meinem Fall nicht Typeconverter Staaten Klasse zutraf

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