2010-10-28 40 views
2

J'essaie d'utiliser une grille de propriétés pour afficher des données. Je dois écrire StringConverters pour mes constantes de chaînes prédéfinies afin qu'elles puissent être affichées dans une zone de liste déroulante. Envisager une liste de couleurs et une autre liste d'angles 0,90,180,270StringConverter GetStandardValueCollection

Il y a beaucoup de ces listes que je veux afficher sur la grille.

Je vous écris de nouvelles classes provenant de StringConverters et GetStandardValues ​​prépondérants

class AngleConverter : StringConverter 
{ 
    string[] Units = { "0", "90", "180","270" }; 
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
    { 
     return new StandardValuesCollection(Units); 
    } 
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
} 

Classe UnitConverter: ... Même code, sauf modification du tableau de chaînes. J'utilise cette classe avant la propriété comme [TypeConverter (typeof (AngleConverter))]. Je dois créer une nouvelle classe si je veux ajouter une liste de chaînes à afficher dans une zone de liste sur la grille.

Existe-t-il un moyen générique de le faire sans créer de nouvelles classes à chaque fois.

Merci --Hari

Répondre

2

EDIT: D'après la réponse de Thomas Lycken à ce link, il pourrait être utile si vos biens sont énumérations ...

Je ne sais pas si vous pouvez éviter d'écrire de nouveaux classes ou non. Je ne suis pas assez familier avec ce que vous faites pour savoir s'il y a une manière sensiblement meilleure ou plus facile ou non. Cela dit, vous pouvez réduire votre classe un peu en faisant une chose de classe de base abstraite comme ceci:

class MyBaseStringConverter : StringConverter 
{ 
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
    { 
     //Call the abstract GetValues function here. 
     return new StandardValuesCollection(GetValues()); 
    } 
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
    protected abstract string [] GetValues(); 
} 

public AngleConverter : MyBaseStringConverter 
{ 
    protected override string [] GetValues() 
    { 
    return new string [] { "0", "90", "180", "270" }; 
    } 
} 

public ColorConverter : MyBaseStringConverter 
{ 
    protected override string [] GetValues() 
    { 
    return new string [] { "Red", "Green", "Blue" }; 
    } 
} 
2

Eh bien, j'écrirais un autre attribut pour contenir les valeurs standard. Ensuite, votre classe dérivée de StringConverter détecterait simplement cet attribut et saisir les valeurs à partir de là:

private string _unit = "m/s"; 

[PropertyValueDisplayedAs(new string[] { "m/s", "km/h" })] 
[TypeConverter(typeof(MyStringConverter))] 
public string ConstraintString 
{ 
    get { return _unit; } 
    set { _unit = value; } 
} 

Votre convertisseur ressemblerait à ceci:

public class MyStringConverter : StringConverter 
{ 
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
    { 
     return true; 
    } 

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
    { 
     PropertyValueDisplayedAsAttribute attr = (PropertyValueDisplayedAsAttribute)context.PropertyDescriptor.Attributes[typeof(PropertyValueDisplayedAsAttribute)]; 
     return new StandardValuesCollection(attr.DisplayedValues); 
    } 
} 

Bien sûr, vous pourriez mettre en cache les valeurs standard dans le convertisseur pour éviter en leur demandant s'ils ne changent pas par propriété. Je vais vous laisser écrire PropertyValueDisplayedAsAttribute qui est un attribut très simple contenant une collection.